큰 GZIPPED 파일의 압축되지 않은 크기를 처리하는 가장 빠른 방법


24

파일이 압축되면 압축되지 않은 파일 크기가 무엇인지 (압축하지 않은 상태), 특히 압축되지 않은 파일의 크기가 4GB보다 큰 경우 신속하게 쿼리하는 방법이 있습니까?

RFC https://tools.ietf.org/html/rfc1952#page-5 에 따르면 파일의 마지막 4 바이트를 쿼리 할 수 ​​있지만 압축되지 않은 파일이 4GB보다 크면 값은uncompressed value modulo 2^32

이 값은을 실행하여 검색 할 수도 gunzip -l foo.gz있지만 "압축되지 않은"열에 uncompressed value modulo 2^32는 위에서 설명한대로 바닥 글을 읽을 때 다시 포함 됩니다.

압축을 풀지 않은 파일 크기를 먼저 압축 해제하지 않고 파일 크기를 얻는 방법이 있는지 궁금합니다.이 방법은 압축 된 파일에 50GB 이상의 데이터가 포함되어 있고 gzcat foo.gz | wc -c


편집 : 4GB 제한은 OSX에 포함 된 유틸리티 man페이지 에서 공개적으로 인정됩니다 gzip( Apple gzip 242)

  BUGS
    According to RFC 1952, the recorded file size is stored in a 32-bit
    integer, therefore, it can not represent files larger than 4GB. This
    limitation also applies to -l option of gzip utility.

2
좋은 질문 +1! 나는 대답이 아니오라고 생각합니다. 헤더 형식은 그러한 파일 크기가 예상되기 전의 시간에 설계되었습니다. 생각해 보면 gzip이 커뮤니티의 많은 사용자보다 나이가 많아야합니다!
— Celada

2
gzip23 살짜리 아이들이 많이 돌아 다니는 것에 놀랐습니다. 나는 몇 가지가 있다고 확신하지만 중간 나이는 30-35 정도입니다.
— Bratchley

2
xz제한이없는 것으로 전환하기에 좋은시기 일 수 있습니다 . GNU가 (으)로 전환 중 xz입니다.
— Stéphane Chazelas

@ StéphaneChazelas 재미있는. 불행히도 내가 관심있는 파일은 내 통제 범위를 벗어났습니다 (예 : 압축 파일이 수신 됨).하지만 확실히이 xz 문제를 해결하는 것처럼 보입니다 .
— djhworld

답변:


11

가장 빠른 방법은 수정 gzip모드에서 테스트하면 압축 해제 된 바이트 수가 출력되도록 수정하는 것입니다. 7761108684 바이트 파일로 시스템에서

% time gzip -tv test.gz
test.gz:     OK (7761108684 bytes)
gzip -tv test.gz  44.19s user 0.79s system 100% cpu 44.919 total

% time zcat test.gz| wc -c
7761108684
zcat test.gz  45.51s user 1.54s system 100% cpu 46.987 total
wc -c  0.09s user 1.46s system 3% cpu 46.987 total

gzip (Debian에서 사용 가능한 1.6)을 수정하려면 패치는 다음과 같습니다.

--- a/gzip.c
+++ b/gzip.c
@@ -61,6 +61,7 @@
 #include <stdbool.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <inttypes.h>

 #include "closein.h"
 #include "tailor.h"
@@ -694,7 +695,7 @@

     if (verbose) {
         if (test) {
-            fprintf(stderr, " OK\n");
+            fprintf(stderr, " OK (%jd bytes)\n", (intmax_t) bytes_out);

         } else if (!decompress) {
             display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);
@@ -901,7 +902,7 @@
     /* Display statistics */
     if(verbose) {
         if (test) {
-            fprintf(stderr, " OK");
+            fprintf(stderr, " OK (%jd bytes)", (intmax_t) bytes_out);
         } else if (decompress) {
             display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);
         } else {

여전히 실제 데이터를 내부적으로 작성합니까, 아니면 -t이미 이와 관련하여 최적화되어 있습니까? 향상 시간은 출력 시간 만 절약 한 것처럼 보일 정도로 작습니다.
— frostschutz

예, 원본 크기를 파악하기 위해 모든 압축을 풀어야합니다. 이렇게하면 출력 시간 만 절약 할 수 있지만 모든 것이 저장 될 수 있다고 생각합니다.
— Stephen Kitt

흥미 롭습니다. 예, 실제로 작동하려면 코드를 변경해야한다고 생각했습니다. 불행히도 내 경우에는 관심있는 파일이 실제로 내 통제력이 아니므로 외부 당사자로부터 파일을 수신하므로 처음에는 압축 할 수 없습니다. 4GB가 넘는 파일을 완전히 지원하는 유일한 방법은 gzip을 패치하여 12 바이트 바닥 글, 4 바이트 CRC 및 8 바이트 (64 비트)를 파일 크기로 설정하는 것입니다. 그러나 이것은 기존 gzip과의 호환성을 손상시킵니다!
— djhworld

위에서 제공하는 솔루션은 실행 중이더라도 처음에 파일을 압축하지는 않습니다 gzip. gzip압축 파일을 실행 하여 다시 압축하지 않고 확인합니다. (패치는이 개념 증명 빠른 - 및 - 더러운,이 작업을하려면 몇 가지 더 변화가 필요하다 gunzip.)
— 스티븐 키트

트윗 담아 가기 더 나은 / 더 티어 해킹은 해당 데이터를 FCOMMENT현장 에 포함시키는 것 입니다. 이렇게하면 사용자가 바이트 범위를 쿼리하여 해당 데이터를 검색 할 수 있습니다. 이것은 특히 Amazon S3에 저장된 항목에 유용합니다.
— djhworld

0

압축 파일 또는 파일 세트의 크기가 필요한 경우 압축되지 않은 파일 크기 를 포함 tar -z하거나 tar -j대신 사용하는 것이 가장 좋습니다 . 파일 목록을 엿볼 때 사용하십시오 .gziptarlesspipe

aptitude install lesspipe
lesspipe <compressed file> | less

다음 less을 사용하도록 구성된 경우 lesspipe:

less <compressed file>

그래도 시간이 오래 걸릴 수 있음을 명심하십시오. 그러나 시스템의 응답 성이 유지되어 압축 해제 프로세스를 종료 할 수 있습니다.

또 다른 방법은 압축 비율을 기록하고 대신 [text] 파일을 쿼리하는 것입니다.

gzip --verbose file 2>&1 | tee file.gz.log
file:    64.5% -- replaced with file.gz

그래도 실제 파일 크기를 찾으려면 계산이 필요합니다.

예를 들어 tar전체 압축 풀기 프로세스를 통해 파일 크기 또는 이름 만 가져 오는 것을 방지하기 때문에 실제로 큰 크기의 백업으로 수행하는 작업 인으로도 동일한 작업을 수행 할 수 있습니다 .


2
모든 파일 목록을 얻기 위해 tar.gz를 완전히 압축 해제 할 필요는 없습니까?
— frostschutz

실제로 그렇습니다. 이것이 압축되지 않은 파일 크기를 얻을 수있는 유일한 방법입니다. 으로 tar당신이 가지고있는 원래의 파일 크기는 아카이브에 기록. zip반면에 나는 다르게 행동한다고 확신하지 못한다 .

1
이 시점에서 OP는 wc -c명령을 수행 할 수도 있습니다 .
— Bratchley

물론 @Bratchley. 그러나 모든 결과를 얻으려면 상당한 시간이 걸립니다. 따라서 로그 파일 크기에 대한 두 가지 제안.

0

이건 어떤가요

gzip -l file.gz|tail -n1|awk '{print $2}'

numfmt --to=iec $(gzip -l file.gz|tail -n1|awk '{print $2}')

1
OP에 설명 된 것처럼 큰 파일에는 작동하지 않습니다.
— Stephen Kitt

-2
gunzip -c $file | wc -c

시간이 오래 걸리지 만 최종 크기 (바이트)를 제공합니다.


5
이것이 바로 OP가하지 않아도되는 일입니다.
— depquid
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.