답변:
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd -
한 줄로 작업을 수행해야합니다. 숨겨진 파일에도 잘 작동합니다. "*"는 적어도 bash에서 경로 이름 확장으로 숨겨진 파일을 확장하지 않습니다. 아래는 내 실험입니다.
$ mkdir my_directory
$ touch my_directory/file1
$ touch my_directory/file2
$ touch my_directory/.hiddenfile1
$ touch my_directory/.hiddenfile2
$ cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
$ tar ztf my_dir.tgz
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
.
와 *
명령이 될 것입니다, 그래서 cd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..
당신은 예상대로 작동합니다 다음.
$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
cd
디렉토리에 들어가는 것은 꽤 절름발이입니다. 적어도 사용에서 수 pushd
와 popd
경우 tar
와 같은 플래그를하지 않았다 -C
.
-C
tar 스위치를 사용하십시오 .
tar -czvf my_directory.tar.gz -C my_directory .
이 명령 -C my_directory
은 tar에게 현재 디렉토리를로 변경하도록 지시 my_directory
한 다음 .
"현재 디렉토리 전체 추가"(숨겨진 파일 및 하위 디렉토리 포함)를 의미합니다.
수행 -C my_directory
하기 전에 수행 해야합니다. 그렇지 .
않으면 현재 디렉토리에 파일이 있습니다.
tar --create --file=foo.tar -C /etc passwd hosts -C /lib libc.a
" apl.jhu.edu/Misc/Unix-info/tar/tar_65.html 항상 시도 tar -czvf my_directory.tar.gz * -C my_directory
하고 작동하지 않습니다. -C
위치가 중요합니다! 젠장 타르
*
숨겨진 파일 (원래 요구 사항)이 포함되지 않습니다.
평소와 같이 아카이브를 작성하고 다음을 사용하여 추출 할 수도 있습니다.
tar --strip-components 1 -xvf my_directory.tar.gz
--strip-components
이것이 GNU 확장 이라는 생각입니다 .
--transform
/를 살펴보면 --xform
파일이 아카이브에 추가 될 때 파일 이름을 마사지 할 수 있습니다.
% mkdir my_directory
% touch my_directory/file1
% touch my_directory/file2
% touch my_directory/.hiddenfile1
% touch my_directory/.hiddenfile2
% tar -v -c -f my_dir.tgz --xform='s,my_directory/,,' $(find my_directory -type f)
my_directory/file2
my_directory/.hiddenfile1
my_directory/.hiddenfile2
my_directory/file1
% tar -t -f my_dir.tgz
file2
.hiddenfile1
.hiddenfile2
file1
발현이 유사하다 변형 sed
, 우리 이외 세퍼레이터 사용할 수 /
( ,
위의 예 참조).
https://www.gnu.org/software/tar/manual/html_section/tar_52.html
--xform
여러 경로에 대해 여러 번 전달할 수도 있습니다 .
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
일부 조건 (파일, 디렉토리 및 심볼릭 링크 만 아카이브) :
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
아래는 불행히도 ./
아카이브에 상위 디렉토리 가 포함되어 있습니다.
tar -czf mydir.tgz -C /my/dir .
--transform
구성 옵션 을 사용하여 모든 파일을 해당 디렉토리 밖으로 이동할 수 있지만 .
디렉토리 자체 는 제거되지 않습니다 . 명령을 길들이는 것이 점점 어려워지고 있습니다.
magnus 'answer$(find ...)
와 같이 명령에 파일 목록을 추가하는 데 사용할 수 있지만 "파일 목록이 너무 깁니다"오류가 발생할 수 있습니다. 가장 좋은 방법은 다음과 같이 tar 옵션 과 결합하는 것입니다 .-T
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
기본적으로 디렉토리 아래의 모든 파일 ( -type f
), 링크 ( -type l
) 및 하위 디렉토리 ( -type d
)를 나열 하고을 사용하여 모든 파일 이름을 상대적으로 -printf "%P\n"
만든 다음 tar 명령으로 전달하십시오 (을 사용하여 STDIN에서 파일 이름을 가져옵니다 -T -
). -C
옵션은 상대 이름을 가진 파일의 위치 타르가 알 수 있도록 필요합니다. 이 --no-recursion
플래그는 tar가 아카이브하도록 지시 된 폴더로 중복되지 않도록합니다 (중복 파일을 발생시킵니다).
파일 이름으로 특별한 작업을 수행해야하는 경우 (필터링, 심볼릭 링크 등)이 find
명령은 매우 강력 tar
하며 위 명령 의 일부를 제거하여 테스트 할 수 있습니다 .
$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore
예를 들어 PDF 파일을 필터링하려면 추가 ! -name '*.pdf'
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore
이 명령은 printf
(GNU에서 사용 가능) 사용 하여 상대 경로로 결과를 인쇄하도록 find
지시 find
합니다. 그러나 GNU가없는 경우 find
경로를 상대적으로 만들 수 있습니다 (부모를 제거하십시오 sed
).
find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
이 답변 은 대부분의 상황에서 작동합니다. 그러나 파일 이름이 예를 들어 ./file1
just가 아닌 tar 파일에 어떻게 저장되는지 확인하십시오 file1
. 이 방법을 사용하여 BuildRoot 에서 패키지 파일로 사용되는 tarball을 조작 할 때 문제가 발생한다는 것을 알았습니다 .
한 가지 해결책은 Bash globs를 사용하여 다음을 제외한 모든 파일을 나열하는 것입니다 ..
.
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
이것은 이 답변 에서 배운 요령 입니다.
이제 tar는 ..?*
또는 일치하는 파일이 없으면 오류를 반환 .[^.]*
하지만 여전히 작동합니다. 오류가 문제인 경우 (스크립트에서 성공을 확인하는 중) 다음과 같이 작동합니다.
shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob
지금은 쉘 옵션을 망쳐 놓고 있지만 *
숨겨진 파일과 일치 하는 것이 더 깔끔하다고 결정할 수 있습니다.
shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob
*
현재 디렉토리에서 쉘이 차지하는 곳에서는 작동하지 않을 수도 있으므로 다음을 사용하십시오.
shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob
tar: start.sh: Cannot stat: No such file or directory
발생합니다. 현재 디렉토리의 모든 파일에서 발생합니다! 이것을 피하려면 어떻게해야합니까?
cd my_directory
tar zcvf ../my_directory.tar.gz *
다음 Bash 함수를 제안합니다 (첫 번째 인수는 dir의 경로이고 두 번째 인수는 결과 아카이브의 기본 이름입니다).
function tar_dir_contents ()
{
local DIRPATH="$1"
local TARARCH="$2.tar.gz"
local ORGIFS="$IFS"
IFS=$'\n'
tar -C "$DIRPATH" -czf "$TARARCH" $( ls -a "$DIRPATH" | grep -v '\(^\.$\)\|\(^\.\.$\)' )
IFS="$ORGIFS"
}
이런 식으로 실행할 수 있습니다 :
$ tar_dir_contents /path/to/some/dir my_archive
my_archive.tar.gz
현재 디렉토리 내에 아카이브를 생성합니다 . 숨겨진 (. *) 요소 및 파일 이름에 공백이있는 요소와 함께 작동합니다.
이것이 저에게 효과적입니다.
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')
당신은 또한 사용할 수 있습니다
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')
첫 번째 명령에서 find 는 my_dir 의 파일 및 서브 디렉토리 목록을 리턴합니다 . 그러나 my_dir 디렉토리 자체는 해당 목록에 '.'로 포함됩니다. -printf 매개 변수는 포함한 전체 경로를 제거합니다 '.' 그리고 또한crlf 그러나, 그 우주형식 문자열에서 '%의 P' 의 printf와 파일 및 하위 디렉토리 목록에 남은 잎 my_dir 과 결과의 선도적 인 공간을 볼 수 있습니다 찾기 명령.
TAR에는 문제가되지 않지만이를 수정 하려면 두 번째 명령에서와 같이 -mindepth 1 을 추가하십시오 .
pax를 사용하십시오.
Pax는 더 이상 사용되지 않는 패키지이지만 완벽하고 간단한 방식으로 작업을 수행합니다.
pax -w > mydir.tar mydir
# tar all files within and deeper in a given directory
# with no prefixes ( neither <directory>/ nor ./ )
# parameters: <source directory> <target archive file>
function tar_all_in_dir {
{ cd "$1" && find -type f -print0; } \
| cut --zero-terminated --characters=3- \
| tar --create --file="$2" --directory="$1" --null --files-from=-
}
공백이나 다른 특이한 문자가있는 파일 이름을 안전하게 처리합니다. 선택적으로 -name '*.sql'
find 명령에 유사하거나 유사한 필터를 추가하여 포함 된 파일을 제한 할 수 있습니다.
tar -czf
입니까? 필자의 경우 디렉토리가 아닌 파일 만 저장합니다. 때 난 그냥tar
디렉토리 그것을 포함하지만에tar -czf
그것은 단지 파일을 추가합니다.