Como descompactar dados zlib no UNIX?

86

Eu criei dados compactados com zlib no Python, assim:

import zlib
s = '...'
z = zlib.compress(s)
with open('/tmp/data', 'w') as f:
    f.write(z)

(ou uma linha no shell: echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data )

Agora, quero descompactar os dados no shell. Nem zcat nem uncompress work:

$ cat /tmp/data | gzip -d -
gzip: stdin: not in gzip format

$ zcat /tmp/data 
gzip: /tmp/data.gz: not in gzip format

$ cat /tmp/data | uncompress -
gzip: stdin: not in gzip format

Parece que eu criei um arquivo semelhante ao gzip, mas sem nenhum cabeçalho. Infelizmente não vejo nenhuma opção para descompactar esses dados brutos na página man do gzip, e o pacote zlib não contém nenhum utilitário executável.

Existe um utilitário para descompactar dados brutos do zlib?

    
por mykhal 21.09.2011 / 00:08

10 respostas

121

Também é possível descompactá-lo usando + , se você não tem, ou deseja use ou outras ferramentas.
O truque é prefixar o < href="http://www.onicos.com/staff/iz/formats/gzip.html"> gzip magic number e compress method para os dados reais de zlib.compress :

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - /tmp/data |gzip -dc >/tmp/out

Edições:
@ d0sboots comentou: Para dados RAW Deflate, você precisa adicionar mais 2 bytes nulos:
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"

Esse Q on SO fornece mais informações sobre essa abordagem. Uma resposta lá sugere que há também um rodapé de 8 bytes.

Usuários @ Vitali-Kushner e @ mark-bessey relataram sucesso mesmo com arquivos truncados, portanto, um rodapé gzip não parece estritamente necessário.

@ tobias-kienzler sugeriu essa função para as :
zlipd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - $@ |gzip -dc)

    
por 25.09.2012 / 05:36
55

O usuário @tino comentou abaixo a resposta do OpenSSL, mas acho que isso deve ser separado:

zlib-flate -uncompress < FILE

Eu tentei isso e funcionou para mim.

zlib-flate pode ser encontrado no pacote qpdf (no Debian Squeeze e no Fedora 23, de acordo com comentários em outras respostas)

    
por 01.11.2015 / 04:18
51

Eu encontrei uma solução (uma das possíveis), usando openssl :

$ openssl zlib -d < /tmp/data

ou

$ openssl zlib -d -in /tmp/data

* NOTA: a funcionalidade zlib está aparentemente disponível em versões recentes do openssl > = 1.0.0 (o OpenSSL deve ser configurado / construído com a opção zlib ou zlib-dynamic, o último é o padrão)

    
por 17.10.2011 / 02:56
21

Eu recomendo pigz de Mark Adler , coautor da biblioteca de compactação zlib. Execute pigz para ver as bandeiras disponíveis.

Você notará:

-z --zlib Compress to zlib (.zz) instead of gzip format.

Você pode descompactar usando o sinalizador -d :

-d --decompress --uncompress Decompress the compressed input.

Supondo um arquivo chamado 'teste':

  • pigz -z test - cria um arquivo compactado zlib chamado test.zz
  • pigz -d -z test.zz - converte test.zz para o arquivo de teste descompactado

No OSX, você pode executar brew install pigz

    
por 26.09.2016 / 14:27
10

zlib implementa a compactação usada pelo gzip, mas não o formato do arquivo. Em vez disso, você deve usar o % módulogzip , que usa zlib .

import gzip
s = '...'
with gzip.open('/tmp/data', 'w') as f:
    f.write(s)
    
por 21.09.2011 / 00:10
3

Isso pode ser feito:

import glob
import zlib
import sys

for filename in sys.argv:
    with open(filename, 'rb') as compressed:
        with open(filename + '-decompressed', 'wb') as expanded:
            data = zlib.decompress(compressed.read())
            expanded.write(data)

Em seguida, execute-o assim:

$ python expander.py data/*
    
por 21.09.2011 / 00:20
2

O programa de exemplo zpipe.c encontrado aqui pelo próprio Mark Adler (vem com a distribuição fonte da biblioteca zlib) é muito útil para esses cenários com dados brutos do zlib. Compile com cc -o zpipe zpipe.c -lz e para descompactar: zpipe -d < raw.zlib > decompressed . Também pode fazer a compactação sem o sinalizador -d .

    
por 06.03.2018 / 11:38
1

Você pode usar isso para compactar com zlib:

openssl enc -z -none -e < /file/to/deflate

E isso para esvaziar:

openssl enc -z -none -d < /file/to/deflate
    
por 27.06.2016 / 07:48
1

No macOS, que é um UNIX totalmente compatível com POSIX (formalmente certificado!), OpenSSL não possui zlib support, não há zlib-flate e a primeira solução funciona tão bem quanto todas as soluções Python, a primeira solução requer que os dados ZIP estejam em um arquivo e todas as outras soluções forçam você a criar um script Python.

Aqui está uma solução baseada em Perl que pode ser usada como linha de comando one-liner, obtém sua entrada via pipe STDIN e funciona imediatamente com um macOS recém-instalado:

cat file.compressed | perl -e 'use Compress::Raw::Zlib;my $d=new Compress::Raw::Zlib::Inflate();my $o;undef $/;$d->inflate(<>,$o);print $o;'

Mais bonito formatado, o script Perl é assim:

use Compress::Raw::Zlib;
my $decompressor = new Compress::Raw::Zlib::Inflate();
my $output;
undef $/;
$decompressor->inflate(<>, $output);
print $output;
    
por 19.06.2018 / 14:39
-3
zcat -f infile > outfile 

funciona para mim no fedora25

    
por 17.10.2017 / 09:27