tar 파일 만, 디렉토리 없음


16

셸 스크립트를 작성하여 파일 만 찾은 다음 목록을 tar로 전달할 수 있지만 tar에 내장 된 기능이 단일 명령 줄에서 이미 수행 가능한지 궁금합니다.

예를 들어 --no-recursion스위치를 찾았 지만 내가 할 때 :

tar --no-recursion -cvf mydir.tar mydir

디렉토리의 항목 이름 (하위 디렉토리 포함) 만 아카이브하지만 파일은 아카이브하지 않습니다.

나는 또한 시도했다 :

 tar --no-recursion -cvf mydir.tar mydir/*

그러나 파일 만 아카이브하지만 서브 디렉토리 의 이름 도 아카이브합니다 .

디렉토리없이 tar 파일 만 알려주는 방법이 있습니까?


5
간단히 설명하면 "평평한"구조의 아카이브 (예 : 모든 파일이 하나의 디렉토리에 혼합되어 있음)를 작성 하시겠습니까?
rozcietrzewiacz

1
새 디렉토리 find mydir -type f |xargs cp -t tempdir를 만든 다음 tar tempdir을 만들 수 있습니다 .
케빈

@rozcietrzewiacz 예, 단순하지만 하위 디렉토리가 아닌 해당 디렉토리에서만 가능합니다.
ateiob

1
좋아, 네가하려는 일을 본 것 같아 어때find mydir -depth 1 -type f | xargs tar cf mydir.tar
Kevin

2
아 공간. 대신 find 's -exec를 사용하십시오 find mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} +. 이 +명령은 모든 파일을 xargs와 같은 동일한 명령 줄에 넣습니다.
케빈

답변:


11

camh가 지적했듯이 이전 명령은 파일 이름이 너무 많으면 두 번 이상 실행되며 나중에 호출하면 이전 실행을 자동으로 지 웁니다. 압축하지 않기 때문에 덮어 쓰기 대신 추가 할 수 있습니다.

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar Avf mydir.tar
find mydir -maxdepth 1 -type f -exec tar Avf mydir.tar {} +

사용에 대한 Iocnarz의 답변tar--null-T옵션은 잘 작동합니다. cpio설치 했다면 그것을 사용하는 camh의 대답 도 좋습니다. 그리고 zsh명령에 사용하는 것이 마음에 들지 않으면 zsh glob ( )를 사용하는 Gilles의 대답*(.) 이 가장 간단합니다.


열쇠는 -maxdepth옵션이었습니다. 공간을 적절하게 처리하는 최종 답변 :

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar cvf mydir.tar

이것은 또한 작동해야합니다 :

find mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} +

4
이 두 가지 모두에 대해 여러 번 호출 될 수 있습니다 tar. 모두 xargsfind으로 +변형 타르에 전달 될 수있는 인수의 최대 번호가 있습니다. 이로 인해 tar의 두 번째 호출이 첫 번째 출력을 겹쳐 씁니다.
camh

2
xargs 제한을 확장하면 xargs는 기본적으로 최대 128KiB 명령 줄로 설정됩니다. 파일 목록이 더 크면 명령 (tar)을 두 번 이상 호출하여 자동 데이터 손실이 발생합니다. -x데이터 손실 대신 xargs를 강제 종료 하는 데 사용할 수 있으며 자동 데이터 손실 버그보다 우수하지만 여전히 이상적이지는 않습니다. 이 정렬 버그는 처음에는 모든 것이 정상인 것처럼 보이기 때문에 매우 위험하지만 시간이지나면서 파일 목록이 커지면 트리거를 시작하고 백업을 복원하려고 시도 할 때까지 알아 채지 못할 수 있습니다. 그럼 너무 늦었 어
camh

@camh 당신이 옳습니다. 지적 해 주셔서 감사합니다. 이를 반영하여 업데이트했습니다.
케빈

1
-T없이 "tar c"를 사용하면 "최종 답변"이 올바르지 않습니다. 부분적인 결과를 얻을 수 있습니다.
eckes

14

find와 함께 사용 tar하려면 가장 좋은 방법은 cpio대신에 사용하는 것입니다 tar.cpiotar 아카이브를 작성할 수 있으며 stdin에서 아카이브 할 파일 목록을 가져 오도록 설계되었습니다.

find mydir -maxdepth 1 -type f -print0 | cpio -o -H ustar -0 > mydir.tar

사용 find하고하는 것은 cpio당신이 할 수 있다는 점에서 더 유닉스-Y 접근 방식 find이 빠져으로 전원을 파일 선택을하고, 수 있도록 cpio보관을한다. cpio시도 할 때 앞서 겪는 문제를 쉽게 해결할 수 있다는 점 에서이 간단한 사용법을 배우는 것이 좋습니다 tar.


훌륭한! 나는 먼 옛날에 cpio를 사용했지만 ustar 옵션을 알지 못했습니다.
Ian McGowan

2
이것은 받아 들인 대답보다 훨씬 나에게 효과적이었습니다.
데일 앤더슨

1
그냥 니트. -maxdepth 1은 -type f 앞에 와야합니다. 그렇지 않으면 일부 결과에서 경고가 표시됩니다.
kdubs

@kdubs 감사합니다. -maxdepth이전에 답변을 업데이트했습니다 -type.
camh

3

귀하의 요구 사항을 이해하지 못했습니다. mydir하위 디렉토리가 아닌 일반 파일을 저장하려면 가장 쉬운 방법은 zsh를 사용하는 것입니다. 여기서 정규 파일을 일치시키는 것만 . glob 한정자 를 사용하면됩니다 .

tar cf mydir.tar mydir/*(.)

3

당신은 심지어 사용할 수 있습니다 find ... -print0tar ... --null직접 사용하지 않고 xargs전혀.

find . -maxdepth 1 -type f -print0 | tar cvf mydir.tar --null -T -

주어진 예에서, (디렉토리가 아닌) 파일 경로 만에서 로 전달되기 때문에에 대한 --no-recursion옵션 tar이 필요하지 않습니다.findtar .

그러나 다음 예제에서 --no-recursion옵션을 사용하면 디렉토리를 이중으로 아카이브 tar할 수 없습니다 tar. 그 find대신 디렉토리 트리 재귀를 수행합니다 tar.

# compare
find . -print0 | tar cf mydir.tar --null -T -
tar -tf mydir.tar | nl

find . -print0 | tar cf mydir.tar --null --no-recursion -T -
tar -tf mydir.tar | nl

2

소개 단락으로 man tar 말한 것처럼 (마지막 문장)

디렉토리 이름을 사용한다는 것은 항상 아래의 서브 디렉토리가 아카이브에 포함되어야 함을 의미합니다.

귀하의 질문에 대한 "아니오"답변으로 이해합니다.


타르 지금 수많은 제외 meachisms를 포함하는 것을 제외하고는 좋은 캐치, (예를 들어 --no-recursion, --exclude-tag등). 나는 --exclude-tag유망 해 보이지만 찾고 있는 것과 정반대 인 것으로 보입니다.
ateiob

나는 이것을 시도했고 긴 경로 이름에서 문자가 제거되는 것을 보았다. camh가 제안한대로 tar를 -T 및 --null과 함께 사용하면이 문제를 피할 수 있습니다.
Paul Brannan

1
star -c -C startdir -find . ! -type d > out.tar

생략 -C startdir및 교체 .와 함께startdir아카이브에 표시되어야 경우 .

이것은 libfind의 기능을 기반으로 가장 효율적인 방법입니다. Libfind는 또한 -chown -chgrp -chmodstruct stat를 수정하고 다른 메타 데이터를 아카이브 할 수있는 기본 을 제공합니다 . 또한 목록 및 추출 모드에서 작동하며 많은 경우 전체 아카이브를 추출 할 필요가 없습니다.


모드 -find에서 사용할 수 있습니다 -copy. 매뉴얼 페이지 개요는 당신이 할 수 있다고 제안하지만 ( 폴더 구조를 유지하면서 수정 된 파일을 복사하는 방법에 대한 대답을 시도하는 동안) 작동시킬 수는 없었습니다 (schily-2016-02-10 사용)
Stéphane Chazelas

나는 이것을 오랫동안 테스트하지 않았다. 현재 버그가있을 수 있습니다. 맨 페이지에는 마지막 인수가 추출 디렉토리라고 말하지만 이것을 시도하면 "추출 모드에서 아직 지원되지 않는 경로 인수"가 표시됩니다. 당신이 시도 할 때 이것이 무엇입니까?
schily

예. 매뉴얼 페이지는 또한 -find 이후에 인수를 찾을 수 있다고 말하지만 목적지 디렉토리를 -find 앞에 놓으면 오류가 발생합니다.
Stéphane Chazelas

추출 프로세스에서 찾기 코드를 끄는 코드가 있으며 오류 메시지는 -c를 예상하지만 -copy도 허용해야하는 잘못된 검사에서 나온 것입니다. -copy 모드에서 찾기 파서는 마지막 인수를 포함하지 않아야합니다.
schily

1
최종 솔루션은 이제 sourceforge.net/projects/schilytools/files/schily-2016-03-11.tar.bz2의 schily 도구에 게시되었으며 스타에서 setlocale ()이 누락되어 발생하는 문제를 해결합니다. 에 대한 C directrory star -find.
schily

0

해결책을 찾았을 것입니다.

find mydir -type f -printf '%P\0'|tar czvf mydir.tar.gz -C mydir --null -T -

이것은 약간 비싸지 만 어쨌든 xargs에 의존하지 않기 때문에 작동합니다.


-1

dir = your_dir; cd $ dir; tar -cvf file.tar`find. -최대 깊이 1-타입 f-인쇄`

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