폴더에 포함 된 .gz 파일 추출


13

약 320116 개의 .pdb.gz 파일이 들어있는 폴더가 있습니다. 나는 그들 모두를 압축 해제하고 싶습니다. gunzip * .gz를 사용하면 오류 목록, 즉 인수 목록이 너무 깁니다. 폴더는 약 2GB입니다. 적절한 제안을 부탁드립니다.


이 디렉토리 구조를 장기간 작업해야하는 경우이 디렉토리를 여러 디렉토리로 분할하십시오. 예를 들어 파일 수정 시간 또는 파일 이름을 기준으로합니다.
dan

예, 장기적으로 일해야합니다. 그들은 지금 추출되었습니다 이름을 기준으로 세 개의 폴더로 세분화하고 분류하고 싶습니다. 그렇게하는 쉘 스크립트가 있습니까?
Lily Sharpton

비슷한 질문을 검색하는 것이 좋습니다. 필요에 맞는 것을 찾지 못하면 새로운 질문을하십시오.
dan

답변:


25
find . -name '*.pdb.gz' -exec gunzip {} +

-exec gunzip {} +gunzip명령 행에 많은 파일 이름을 제공 하지만 너무 많지는 않습니다. 각 파일마다 -exec gunzip {} \;새로운 gunzip프로세스를 시작하는 것보다 효율적 입니다.


3
하나 find, 적은 gunzip!
dan

2
"+"는 GNUism이므로 * BSD와 같은 GNU 이외의 시스템에서는 작동하지 않습니다.
Reinstate Monica-M. Schröder

3
이후 버전의 BSD find는 "+"표기법을 허용합니다. 예를 들어, BSD 10.1 find매뉴얼 페이지를 참조하십시오 . OS X (적어도 10.9 이상)에 적용됩니다.
혈장

7

"인수 목록이 너무 깁니다"오류가 발생할 때마다 원하는 인수의 하위 집합을 사용하여 원하는 명령을 여러 번 호출하여이 문제를 해결할 수 있습니다. xargs자동으로 수행하는 데 도움이되는 도구입니다.

find . -type f -a -name \*.pdb.gz -print0 | xargs -0 gunzip

이것은 -execdir gunzip "{}" \;xargs가 각 파일에 대해 개별적으로 gunzip을 호출 하는 것과 같은 비 효율성을 갖지 않습니까? 맨 페이지를 읽었습니다.
gogoud

5
아니요, 명령 줄 xargs에 맞는만큼의 파일 이름을 채 웁니다 gunzip. 시도 해봐! 6 개의 인수 모두로 한 번만 echo a b c d e f | xargs echo호출 echo하므로 한 줄의 출력 (아주 쓸모없는 명령이지만 !!!!)을 볼 수 있지만 명령을 xargs호출 할 때마다 최대 3 개의 인수 만 제공 echo a b c d e f | xargs -n 3 echo하면 2 줄의 출력을 얻습니다. .
Celada

4
옵션을 사용하면 시스템의 정확한 매개 변수에 따라 여러 프로세스를 병렬로 실행할 수 xargs있다는 이점 -P이 있습니다 gunzip.
psmears

-P@psmears 에 대한 포인터 주셔서 감사합니다 . 이제 나도 무언가를 배웠다!
Celada

1

나는 이것이 작동해야한다고 생각한다. 처리하기 위해 각 파일의 경로 / 이름을 개별적으로 gunzip으로 전달한다.

find /my/dir -name "*.pdb.gz" -execdir gunzip "{}" \;

1
파일 당 한 번 gunzip을 실행합니다. 그 비 효율성을 피하는 약간 다른 방법 은 John1024의 답변 을 참조하십시오 .
Celada

@Celada 이것은 의도적이었습니다. 내 관심사는 +를 사용하면 건집 과부하로 인해 오류 메시지가 다시 발생할 수 있다는 것입니다. John1024의 방법이 효과가 있으면 기술적으로 더 효율적이지만 효과가 없으면 효과가 있습니다.
gogoud

1
find+xargs명시 적으로 염두에 정확히 문제에 디자이너. 운영 체제의 한계를 초과하지 않으면 서 항상 가능한 많은 인수를 제공합니다. 때문에, 그런데, 그것은 이다 운영 체제 제한과는 아무 gunzip.
Celada

1
@Celada 해당 정보에 감사드립니다. 아마도 '+'gunzip을 사용하면 두 번 이상 호출되지만 320,000 회 미만으로 호출 될 수 있습니까?
gogoud

1
옳은.
Celada

1

이 방법으로 시도하십시오 :

find . -name '*.gz' -exec gunzip {} \;

3
gunzip파일 당 한 번씩 실행 됩니다. 그 비 효율성을 피하는 약간 다른 방법 은 John1024의 답변 을 참조하십시오 .
Celada

* .gz에서 *를 피하십시오.
user253751

1

멀티 코어 머신을 사용하는 경우 사용 gunzip이 머신의 기능을 최대한 활용하지 못할 수 있습니다. 이를 위해서는 여러 gunzip개의을 병렬 로 실행해야합니다 . 어떤 터미널이 어떤 터미널에서 수행되는지 추적하는 것은 번거롭지 만 GNU 병렬로 쉽게 수행 할 수 있습니다.

find . -name "*.gz" | parallel -X gunzip {}

1
인수 목록 parallel이 너무 길어서 실패하지 않습니까?
user253751

@immibis 예, 원래 문제를 잊었습니다. 게시물을 업데이트하겠습니다
Anthon

하지 않습니다 아직 까지 인수 목록이 있기 때문에 실패 find너무 깁니다?
user253751

1
예, 그러나 모든 파일 이름을 find의 명령 줄 에 전달합니다 .
user253751

오늘이 질문에 대답하기에 좋은 날이 아닌 것 같습니다.-name
Anthon

-1

find하위 폴더는 언급하지 않았으므로이를 사용할 필요 는 없습니다. 당신이해야 할 일은 :

for f in *.gz;do gunzip $f;done

4
당신은 필요 find는 320,116 산란을하지 않으려면 gunzip프로세스를이 루프가하는 것처럼.
존 WH 스미스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.