A maneira mais rápida de trabalhar com tamanho descompactado de um arquivo GZIPPED grande

21

Quando um arquivo é gzipado, há uma maneira de consultá-lo rapidamente para dizer qual é o tamanho do arquivo descompactado (sem descompactá-lo), especialmente nos casos em que o arquivo descompactado é > 4 GB de tamanho.

De acordo com o link do RFC, você pode consultar os últimos 4 bytes do arquivo, mas se o arquivo descompactado foi > 4GB então o valor representa apenas o uncompressed value modulo 2^32

Esse valor também pode ser recuperado executando gunzip -l foo.gz , no entanto, a coluna "descompactada" apenas contém uncompressed value modulo 2^32 novamente, presumivelmente porque está lendo o rodapé como descrito acima.

Eu queria saber se existe uma maneira de obter o tamanho do arquivo descompactado sem ter que descomprimi-lo primeiro, isso seria especialmente útil no caso em que os arquivos gzipados continham mais de 50 GB de dados e demorariam um tempo para descompactar usando métodos como gzcat foo.gz | wc -c

EDIT: A limitação de 4GB é abertamente reconhecida na página man do utilitário gzip incluído no OSX ( 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.
    
por djhworld 07.02.2015 / 11:17

4 respostas

10

Eu acredito que o caminho mais rápido é modificar gzip para que o teste no modo detalhado produza o número de bytes descomprimidos; no meu sistema, com um arquivo de 7761108684 bytes, recebo

% 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

Para modificar o gzip (1.6, como disponível no Debian), o patch é o seguinte:

--- 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 {
    
por 07.02.2015 / 15:22
0

Se você precisar do tamanho de um arquivo compactado ou conjunto de arquivos, sua melhor opção é usar tar -z ou tar -j em vez de gzip , pois tar inclui o tamanho dos arquivos descompactados. Use lesspipe para espiar a lista de arquivos:

aptitude install lesspipe
lesspipe <compressed file> | less

Se less estiver configurado para usar lesspipe :

less <compressed file>

Tenha em mente que pode levar muito tempo embora. No entanto, o seu sistema continua a responder, o que lhe permite eliminar o processo de descompressão.

Outra abordagem seria registrar a taxa compactada e consultar esse arquivo [text]:

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

Requer computação para encontrar o tamanho real do arquivo.

Você também pode fazer o mesmo com tar , que é de fato o que eu faço com backups grandes, pois evita a execução de todo o processo de descompactação para obter apenas um tamanho ou nome de arquivo, por exemplo.

    
por 07.02.2015 / 12:02
0

E sobre

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

numfmt --to=iec $(gzip -l file.gz|tail -n1|awk '{print $2}')
    
por 08.06.2018 / 12:51
-2
gunzip -c $file | wc -c

Isso levará muito tempo, mas fornecerá o tamanho final em bytes.

    
por 20.04.2016 / 17:13