디렉토리 자체를 포함하지 않고 파일 및 폴더 디렉토리를 어떻게 tar합니까?


382

나는 일반적으로 :

tar -czvf my_directory.tar.gz my_directory

my_directory에 모든 항목 (숨겨진 시스템 파일 포함)을 포함 시키려고하지만 디렉토리 자체는 포함시키지 않으려면 어떻게해야합니까? 나는 원하지 않는다 :

my_directory
   --- my_file
   --- my_file
   --- my_file

내가 원하는:

my_file
my_file
my_file

이것이 기본 동작 tar -czf입니까? 필자의 경우 디렉토리가 아닌 파일 만 저장합니다. 때 난 그냥 tar디렉토리 그것을 포함하지만에 tar -czf그것은 단지 파일을 추가합니다.
Durga Swaroop

답변:


233
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

2
공백이나 다른 특수 문자가있는 파일에서도 작동합니다. 잘 했어!
PanCrit

29
완벽하지 않음-tar 파일에 '.'이 포함되어 있습니다. 또한 file1 대신 ./file1입니다. 아래의 mateusza의 솔루션을 사용하여 tar를 풀 때 --strip-components를 사용하십시오.
Ivan

23
바꿀 경우 @Ivan .*명령이 될 것입니다, 그래서 cd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..당신은 예상대로 작동합니다 다음.
Anonymous

3
@jmathew 서브 쉘을 사용하여 현재 쉘의 작업 디렉토리가 변경되지 않도록 할 수도 있습니다.$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
Alec

나는 그것이 오래된 대답이라는 것을 알고 있지만 cd디렉토리에 들어가는 것은 꽤 절름발이입니다. 적어도 사용에서 수 pushdpopd경우 tar와 같은 플래그를하지 않았다 -C.
Andris

667

-Ctar 스위치를 사용하십시오 .

tar -czvf my_directory.tar.gz -C my_directory .

이 명령 -C my_directory은 tar에게 현재 디렉토리를로 변경하도록 지시 my_directory한 다음 ."현재 디렉토리 전체 추가"(숨겨진 파일 및 하위 디렉토리 포함)를 의미합니다.

수행 -C my_directory하기 전에 수행 해야합니다. 그렇지 .않으면 현재 디렉토리에 파일이 있습니다.


5
+1 감사합니다! 빌어 먹을 '.' 나는 실종되었다. 너무 악화
JCotton

14
"대부분의 옵션과 달리 -C는 처리 할 파일 목록 내에서 발생하는 시점에 처리됩니다. 다음 명령을 고려하십시오. 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위치가 중요합니다! 젠장 타르
m-ric

57
완벽하지 않음-tar 파일에 '.'이 포함되어 있습니다. 또한 file1 대신 ./file1입니다. 아래의 mateusza의 솔루션을 사용하여 tar를 풀 때 --strip-components를 사용하십시오.
Ivan

3
@Superole는 다음 쉘은 타르를 실행하기 전에 와일드 카드를 substitues. 또한 와일드 카드를 사용하면 *숨겨진 파일 (원래 요구 사항)이 포함되지 않습니다.
dubek

28
를 만듭니다. .tar.gz의 루트 디렉토리로
Anonymous

59

평소와 같이 아카이브를 작성하고 다음을 사용하여 추출 할 수도 있습니다.

tar --strip-components 1 -xvf my_directory.tar.gz

3
이 솔루션은 모든 요구 사항이 알려지기 전에 생성 된 타르볼로 작업하는 경우에 특히 유용합니다.
Digger

2
--strip-components이것이 GNU 확장 이라는 생각입니다 .
zneak

2
이 답변은 "평상시와 같이"예제를 제공함으로써 향상 될 수 있습니다.
Josh Habdas

33

--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


3
나는 이것을 할 것입니다. 다른 것은 해킹 일뿐입니다!
jwg

2
이것은 훨씬 더 나은 솔루션입니다.
leesei 2016 년

이것이 가장 좋은 해결책입니다.
justhalf

1
좋은 해결책이지만 원인이 될 수 있습니다 file list too long. 내 솔루션은이를 방지하고 더 유연합니다.
aross

이것은 훌륭한 솔루션입니다. --xform여러 경로에 대해 여러 번 전달할 수도 있습니다 .
elig

26

TL; DR

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

비 GNU 찾기

이 명령은 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 -

2
좋은 대답입니다. 매우 정교하고 가장 중요한 것은 문제를 완벽하게 해결하는 것입니다.
Alex

16

이 답변 은 대부분의 상황에서 작동합니다. 그러나 파일 이름이 예를 들어 ./file1just가 아닌 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

1
이 작업을 수행하면 오류가 tar: start.sh: Cannot stat: No such file or directory발생합니다. 현재 디렉토리의 모든 파일에서 발생합니다! 이것을 피하려면 어떻게해야합니까?
BrainStone

@BrainStone 나는 정확히 같은 결과를 얻습니다.
mbmast

15
cd my_directory
tar zcvf ../my_directory.tar.gz *

2
Hal은 숨겨진 파일에 대해 명시 적으로 질문했습니다. . ?? *도 필요합니다.
PanCrit 2016 년

2
-1 : 숨겨진 파일을 tar에 추가하지 않습니다. tbman의 답변을 참조하십시오.
dubek

3

유닉스 / 리눅스 시스템이고 숨겨진 파일 (*에서 놓칠 수있는)에 관심이있는 경우 다음을 수행해야합니다.

cd my_directory
tar zcvf ../my_directory.tar.gz * .??*

Windows에서 숨겨진 파일의 모양을 모르겠습니다.


2

다음 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현재 디렉토리 내에 아카이브를 생성합니다 . 숨겨진 (. *) 요소 및 파일 이름에 공백이있는 요소와 함께 작동합니다.


2
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..

이것은 나를 위해 일했고 "."라는 루트 디렉토리에 모든 파일을 넣지 않고 모든 숨겨진 파일을 포함합니다. tomoe의 답변 에서처럼 :


1
tar.create() {
        local folder="${1}"

        local tar="$(basename "${folder}")".tar.gz

        cd "${folder}" && tar -zcvf "../${tar}" .; cd - &> /dev/null
}

예:

tar.create folder

아니에요.


1

이것이 저에게 효과적입니다.

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 ')

첫 번째 명령에서 findmy_dir 의 파일 및 서브 디렉토리 목록을 리턴합니다 . 그러나 my_dir 디렉토리 자체는 해당 목록에 '.'로 포함됩니다. -printf 매개 변수는 포함한 전체 경로를 제거합니다 '.' 그리고 또한 그러나, 그 형식 문자열에서 '%의 P'printf와 파일 및 하위 디렉토리 목록에 남은 잎 my_dir 과 결과의 선도적 인 공간을 볼 수 있습니다 찾기 명령.

TAR에는 문제가되지 않지만이를 수정 하려면 두 번째 명령에서와 같이 -mindepth 1 을 추가하십시오 .


0

pax를 사용하십시오.

Pax는 더 이상 사용되지 않는 패키지이지만 완벽하고 간단한 방식으로 작업을 수행합니다.

pax -w > mydir.tar mydir

가장 실용적이며 업무 수행 +1
Breno Salgado

이 명령은 내용 : mydir / file1 mydir / file2와 함께 피해야 할 내용으로 mydir.tar를 만듭니다.
Alex

0

내가 찾은 가장 간단한 방법 :

cd my_dir && tar -czvf ../my_dir.tar.gz *


1
숨겨진 파일은 포함되지 않습니다.
asynts

0
# 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 명령에 유사하거나 유사한 필터를 추가하여 포함 된 파일을 제한 할 수 있습니다.


-1
 tar -cvzf  tarlearn.tar.gz --remove-files mytemp/*

폴더가 mytemp 인 경우 위의 항목을 적용하면 폴더의 모든 파일을 압축하여 제거하지만 그대로 둡니다.

 tar -cvzf  tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*

제외 패턴을 제공하고 하위 폴더도 보지 않도록 지정할 수 있습니다


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.