모든 파일이 압축되지 않는 이유와 솔루션 개선 방법


8

약 20K 파일이있는 폴더가 있습니다. 파일은 패턴에 따라 이름이 지정됩니다 ( xy_{\d1,5}_{\d4}\.abc예 :) xy_12345_1234.abc. 이 명령을 사용하여 처음 10K를 압축하고 싶었습니다.

ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz

그러나 결과 파일은 내부에 약 2K 파일 만있었습니다.

ls | sort -n -k1.4,1.9 | head -n10000 | wc -l 그러나 예상대로 10000을 반환합니다.

나는 여기에 기본적인 것을 오해하고있는 것 같습니다 ...

Linux Mint 17.1, GNU tar 1.27.1에서 zsh 5.0.2를 사용하고 있습니다.

편집하다:

@Archemar가 제안한 포크는 결과 파일을 덮어 쓰는 최신 포크와 함께 그럴듯하게 들립니다-파일에는 파일의 '꼬리'가 포함되어 있습니다 -7773 ~ 9999 .

결과 xargs --show-limit: Your environment variables take up 3973 bytes POSIX upper limit on argument length (this system): 2091131 POSIX smallest allowable upper limit on argument length (all systems): 4096 Maximum length of command we could actually use: 2087158 Size of command buffer we are actually using: 131072

교체 -c-r또는 -u내 경우에는 작동하지 않았다. 오류 메시지는tar: Cannot update compressed archives

둘 다 사용 -r하고 -u유효하지 않으며 실패합니다.tar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option

교체 -c로하는 것은 -a물론 잘못된 것 같습니다과 같은 실패 tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options내가 문제를 인정 해달라고 불구 azf하고 Acdtrux나에게 분리 된 것 같다.

편집 2 :

-T는 좋은 방법처럼 보입니다 . 여기 에서 예제를 찾았 습니다 .

그러나 내가 시도 할 때

ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T - 나는 얻다 tar: option requires an argument -- 'T'

글쎄, 아마도 파일 이름이 tar에 도달하지 않습니까? 하지만 마치 그들이 실행될 때 그렇게 보이기 때문에

ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T - 나는 얻다 tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab Cannot stat: File name too long

그렇다면 왜 tar가 파일 이름을 보지 못합니까?


그리고 tar 명령에서 c 대신 c를 시도하면?
Olivier Dulac

5
관련 :ls
8bittree

1
OP의 파일은 까다로운 이름이 없습니다.
Archemar

@ 8bittree-강력한 쉘 스크립트에 대한 일반적인 조언. 그러나 일반 일회용 oneliners를 사용하여 파일 목록으로 작업 할 때 제안하는 것이 무엇입니까?
kostja

1
@kostja 나는 개행 대신 구분 기호로 null 바이트를 사용하는 옵션 find이있는 -print0을 사용합니다. 플래그로 sort처리 할 수 ​​있습니다 -z. head불행하게도 널 바이트 구분 기호를 이해하고 처리하지 않지만, 이 답변이 사용하는 솔루션이 tr스왑 \n\0전후를 head. tar에서 --null -T -null로 구분 된 파일 이름을 읽어야합니다 stdin.
8bittree

답변:


12

당신은 xargs 한도에 도달 했습니까?

xargs --show-limit

시도 :

  • 더미 .tgz파일을 만들다tar czf xy_0_10000.tar.gz /hello/world
  • 교체 -czf-Azf

xarg가 한계에 도달하면 명령을 분기하므로 ultimatly run 명령은

  tar czf xy_0_10000.tar.gz file1 file2 .... file666
  tar czf xy_0_10000.tar.gz file667 file668 ... file1203
  tar czf xy_0_10000.tar.gz file1024 ... file2000

각각의 타르가 이전의 타르를 무시할 때, 당신은 마지막 tar c달리기 만 할 수 있습니다.

편집하다:

1) unbuntu 에 따르면 -r은 동등한man tar-a 추가가 (둘 중 하나)에 의해 수행되는 것처럼 보입니다.-A, --catenate, --concatenate

2) zip(not gzip)을 사용하여 파일을 추가 할 수 있습니다. 아마도 gzip 옵션이 트릭을 수행합니다. (을 사용 | xargs zip -qr xy_0_0000.zip하면 .tar.gz가 아닌 zip 파일이 생성됩니다)

3) @rsanchez의 솔루션을 사용하려면
적절한 방법으로 tar에 옵션을 추가하는 것이 중요합니다.

ls | sort -n -k1.4,1.9 | head -n10000 |tar -czf xy_0_10000.tar.gz -T -

여기서- -T -평균 사용 옵션 -T-인수로 사용 -T(파일 목록을 생성 한 /tmp/foo.lst다음 사용 가능 -T /tmp/foo.lst)


c (= create / overwrite) 대신 a (= add)가 해당 제한을 해결할 수 있습니까?
Olivier Dulac

@OlivierDulac ( 경고 : 이것은 순수한 추측입니다 ) tar는 빈 파일을 만들 수 없으므로 아마 해결되지 않을 것입니다. 당신은 할 수 있습니다 첫 번째 빈 폴더를 압축하고 사용하는 a (add)tar 파일에 파일을 추가 할 수 있습니다. 그런 다음 tar를 열고 폴더를 제거 할 수 있습니다 (7zip 등 사용)
Ismael Miguel

@ismaelmiguel : 파일을 행복하게 만들 것이라고 확신합니다. 그렇지 않다면 :touch xy_0_10000.tar.gz && { _the full command here_ ; }
Olivier Dulac

1
@OlivierDulac 유효하지 않은 .gz파일입니다.
Ismael Miguel

manpages.ubuntu.com/manpages/vivid/en/man1/tar.1.html (15.04)에서 정확한 (12.04)로 돌아가는 모든 맨 페이지 에는 -r추가되지만 -a자동 압축은 동일하지 않습니다. 그리고 -rz: 작동하지 않는 zip디렉토리가 압축되지 않기 때문에 기존 아카이브에 추가 할 수 있지만 tar압축 데이터와 함께 메타 데이터가 압축합니다. 압축되지 않은 아카이브 tar -r로 분할 한 다음 결과를 압축 할 수 있습니다 . 또는 ...
dave_thompson_085

12

필요가 없습니다 xargs. 옵션 을 직접 제공 tar하면 표준 입력 에서 파일 이름읽습니다 .-T -

예를 들어 :

... | tar -T - -czf xy_0_10000.tar.gz

옵션을 잘못 사용하고있는 것 같습니다. 파이프와 함께 작동하지 않습니다. 유무 시도 ...| tar Tczf xy_..., ...| tar Tcz -f xy_... ...| tar -czf xy_... -T 그리고 여러 가지 다른 순열 있지만 얻고 tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options, tar: -f: Cannot stat: No such file or directory사용하는 경우 -f다른 옵션과는 별도로 tar: option requires an argument -- 'T'. 사용 예를 추가해 주시겠습니까?
kostja

@kostja 예제가 추가되었습니다.
rsanchez

많은 감사합니다, rsanchez. 옵션 목록 -T -의 끝에 있는 변형이 tar작동하지 않는 이유는 확실 하지 않지만 예제는 작동했습니다. 불행히도 내 질문에는 실제로 오류의 원인과 가능한 개선의 두 부분이 있습니다. 당신이 후자를 숙달하는 동안 Archemar는 전자보다 뛰어 났고 거의 후자를 가지고 있었다. 둘 다 분명히 도움이 되었기 때문에 어떤 대답을 받아 들일지 잘 모르겠습니다.
kostja

1

ls를 구문 분석 하거나 xargs가 필요 없는 zsh 솔루션으로 다른 두 가지 답변을 보완하고 싶습니다 . 그러나 명령 줄 길이의 한계로 인해 어려움을 겪고 있다면 지금은 확실하지 않습니다.

  1. 를 수정하여 원하는 정렬 키를 생성하는 기능을 정의하십시오 $REPLY.

    sortkey() { REPLY=${REPLY[4,9]} }

    이것은 당신의 sort -n -k1.4,1.9

  2. $files위 함수로 정렬 된 파일 이름으로 배열 을 생성하십시오 .

    files=(*(o+sortkey))

    이것은 ls | sort -n -k1.4,1.9

  3. 처음 10,000 개의 파일을

    ${files[0,9999]}

    이것은 ls | sort -n -k1.4,1.9 | head -n10000

따라서이 모든 것이 트릭을 수행해야합니다.

sortkey() { REPLY=${REPLY[4,9]} }
files=(*(o+sortkey))
tar -czf xy_0_10000.tar.gz ${files[0,9999]}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.