유닉스 - 거대한 .gz 파일을 한 줄씩 분할

유닉스 - 거대한 .gz 파일을 한 줄씩 분할

누군가 아래 요구 사항을 갖고 있다고 확신합니다. 거대한 .gz 파일을 한 줄씩 분할하는 빠른 방법은 무엇입니까? 기본 텍스트 파일에는 1억 2천만 개의 행이 있습니다. 전체 파일을 한 번에 압축할 수 있는 충분한 디스크 공간이 없기 때문에 파일(.gz 또는 내부 .txt)을 3x 40mn 라인 파일로 분할할 수 있는 bash/perl 스크립트나 도구를 아는 사람이 있는지 궁금합니다. . 즉 다음과 같이 호출합니다.

    bash splitter.sh hugefile.txt.gz 4000000 1
 would get lines 1 to 40 mn    
    bash splitter.sh hugefile.txt.gz 4000000 2
would get lines 40mn to 80 mn
    bash splitter.sh hugefile.txt.gz 4000000 3
would get lines 80mn to 120 mn

아마도 이러한 일련의 솔루션을 수행하고 있거나 gunzip -c에 전체 파일의 압축을 풀기에 충분한 공간이 필요할 것입니다(즉, 원래 문제): gunzip -c hugefile.txt.gz | 머리 4000000

참고: 추가 디스크를 얻을 수 없습니다.

감사해요!

답변1

이를 가장 잘 수행하는 방법은 원하는 사항에 따라 다릅니다.

  • 대용량 파일의 단일 부분을 추출하시겠습니까?
  • 아니면 한 번에 모든 부품을 만들고 싶나요?

당신이 원하는 경우파일의 단일 부분, 귀하의 아이디어를 사용하는 gunzip것이 head옳습니다. 당신이 사용할 수있는:

gunzip -c hugefile.txt.gz | head -n 4000000

그러면 표준 출력에서 ​​처음 4000000줄이 출력됩니다. 실제로 데이터로 작업을 수행하기 위해 다른 파이프를 추가하고 싶을 수도 있습니다.

head다른 부분을 얻으려면 다음과 같이 및 의 조합을 사용합니다 tail.

gunzip -c hugefile.txt.gz | head -n 8000000 |tail -n 4000000

두 번째 블록을 얻으려면.

아마도 이러한 일련의 솔루션을 수행하고 있거나 gunzip -c에 전체 파일의 압축을 풀기에 충분한 공간이 필요합니까?

아니요, gunzip -c디스크 공간이 필요하지 않습니다. 메모리에서 모든 작업을 수행한 다음 stdout으로 스트리밍합니다.


만들고 싶다면모든 부품을 한 번에, 단일 명령으로 모두 생성하는 것이 더 효율적입니다. 왜냐하면 입력 파일은 한 번만 읽혀지기 때문입니다. 한 가지 좋은 해결책은 다음을 사용하는 것입니다 split. 자세한 내용은 Jim Mcnamara의 답변을 참조하세요.

답변2

파이프를 분할하려면 gunzip -c 또는 zcat을 사용하여 파일을 엽니다.

gunzip -c bigfile.gz | split -l 400000

분할 명령에 출력 사양을 추가합니다.

답변3

(되감기 불가능한) 스트림에서 작업할 때 '+N' 형식의 꼬리를 사용하여 N 줄부터 시작하는 줄을 가져오는 것이 좋습니다.

zcat hugefile.txt.gz | head -n 40000000
zcat hugefile.txt.gz | tail -n +40000001 | head -n 40000000
zcat hugefile.txt.gz | tail -n +80000001 | head -n 40000000

답변4

.gz 파일을 .gz 파일로 직접 분할:

zcat bigfile.gz | split -l 400000 --filter='gzip > $FILE.gz'

나는 이것이 OP가 원했던 것이라고 생각합니다. 왜냐하면 그는 공간이 많지 않기 때문입니다.

관련 정보