큰 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.