UNIXでzlibデータを解凍する方法は?


106

次のように、Pythonでzlib圧縮データを作成しました。

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

(またはシェル内の1つのライナー。echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data

次に、シェルでデータを圧縮解除します。どちらzcatuncompress動作しません:

$ 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

gzipのようなファイルを作成したようですが、ヘッダーはありません。残念ながら、gzipのマニュアルページにそのような生データを解凍するオプションはありません。また、zlibパッケージには実行可能なユーティリティが含まれていません。

生のzlibデータを圧縮解除するユーティリティはありますか?


回答:


140

または他のツールがない場合、または使用する場合は、標準の + を使用して解凍することもできます。秘Theは、gzipマジックナンバーを追加し、メソッドを実際のデータに圧縮することです:
zlib.compress

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

編集:
@ d0sbootsのコメント:RAW Deflateデータの場合、さらに2バイトのNULLバイトを追加する必要があります:
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"

SOに関するこのQは、このアプローチに関する詳細情報を提供します。そこの答えは、8バイトのフッターもあることを示唆しています。

ユーザー@ Vitali-Kushnerと@ mark-besseyは、切り捨てられたファイルでも成功を報告したため、gzipフッターは厳密には必要ないようです。

@ tobias-kienzlerは、この関数をbashrcに提案し
zlipd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - $@ |gzip -dc)


gzipは機能しませんが、zlib-flateは機能します(pdfページコンテンツストリーム)。
ダニエルS.ヤイツコフ

69

ユーザー@tinoはOpenSSLの回答の下でコメントしましたが、これは別のものであると思います。

zlib-flate -uncompress < FILE

これを試してみたところ、うまくいきました。

zlib-flateパッケージで見つけることができますqpdf(他の回答のコメントによると、Debian SqueezeおよびFedora 23で)


3
他の回答とは対照的に、これはOS Xで動作します。
polym15年

2
@ polym、macOS にどのようにzlib-flate インストールしましたか?どこにも見当たりません。
ワイルドカード

4
@Wildcardの返信が遅くなってすみません。上記コメントで述べたように、qpdfインストールしたパッケージに付属していると思います-またはこの回答の最後の文を見てください:)。また、本当にクールなので、時間があればそれも見てください!brewqpdf
ポリム

qpdfを作成してから、上記のコマンドを実行してください:-)ありがとうございます!
フェルナンドガブリエリ

60

私は解決策を見つけました(可能なものの1つ)、それはopensslを使用しています

$ openssl zlib -d < /tmp/data

または

$ openssl zlib -d -in /tmp/data

*注意:zlib機能は、最近のopensslバージョン> = 1.0.0で明らかに利用可能です(OpenSSLはzlibまたはzlib-dynamicオプションで構成/構築する必要があり、後者がデフォルトです)


25
Debian Squeeze(OpenSSL 0.9.8を搭載)zlib-flateでは、qpdfパッケージに含まれています。のように使用できますzlib-flate -uncompress < FILE
ティノ

7
zlibはOpenSSLの最新バージョンから削除されたため、このヒントは非常に役立ちます@Tino
アレクサンドルクリリン14

1
ありがとう。このソリューションは、「gzip」を使用した回答(「gzip」が「予期しないファイルの終わり」の印刷を中止している間は「openssl」)を使用した回答よりも短い入力ファイルの解凍で優れたエクスペリエンスを提供します。
ダニエルK.

2
@Tinoこれは別の答えでなければなりません
-Catskul

1
@ Tino、Fedora 23のqpdfパッケージでも入手可能です。AlexandrKurilin、zlibは1.0.2d-fipsでも利用可能です。
maxschlepzig

28

私はお勧めpigzをからマーク・アドラー、zlib圧縮ライブラリの共著者。実行pigzして、使用可能なフラグを確認します。

あなたが気づくでしょう:

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

-dフラグを使用して解凍できます:

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

「test」という名前のファイルを想定:

  • pigz -z test -test.zzという名前のzlib圧縮ファイルを作成します
  • pigz -d -z test.zz -test.zzを解凍されたテストファイルに変換します

OSXで実行できます brew install pigz


7
良い発見!zlibファイルを単独で検出できるように見えるためunpigz test.zz、同様に機能します。
ステファンシャゼラス16

データを解凍しませんでした。
サイバーナード

1
@cybernardは、おそらくzlibファイルを持っていません。確認:$>file hello.txt.zz hello.txt.zz: zlib compressed data
snodnipper

11

zlibgzipで使用される圧縮を実装しますが、ファイル形式は実装しません。代わりに、あなたは使うべきgzipモジュール自身が使用しています、zlib

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

[OK]を、私の状況は私が作成したファイルの数十/数百数千を持っているということですので... :)

1
だから...あなたのファイルは不完全です。おそらく、元のデータがまだない場合は、で解凍し、zlibで再圧縮するgzip必要があります。
グレッグヒューギル

6
@mykhal、実際にそれらを圧縮解除できることを確認する前に、なぜ数十万ものファイルを作成したのですか?

3
harpyon、私はそれらを解凍することができ、私はちょうど私が再びpythonでそれを行うにはしたくない場合は以下以上の共通urilityまたはzgipの設定が、そのために使用することができるだろう

3

これはそれをするかもしれません:

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)

次に、次のように実行します。

$ python expander.py data/*

おかげで、私は知っていzlib.decompressます。おそらく私はいくつかのウォーク機能を使用するでしょう。シェルがglobワイルドカードを使用して膨大な量のファイルを処理するかどうかは

expandによって作成されたファイルは、シェルfileコマンドを使用して「zlib圧縮データ」としてチェックアウトされますか?どう?
マイケルアイ

偽のヘッダーを使用しても、nopeは機能しません。
サイバーナード

3

zpipe.c ここでマークアドラー自身が見つけたサンプルプログラム(zlibライブラリのソース配布に付属)は、生のzlibデータを使用したこれらのシナリオに非常に役立ちます。でコンパイルしcc -o zpipe zpipe.c -lzて解凍しますzpipe -d < raw.zlib > decompressed。また、-dフラグなしで圧縮を行うこともできます。


2

完全なPOSIX準拠したUNIX(正式に認定!)でのMacOS上で、OpenSSL何もしているzlib、サポートがないzlib-flateのいずれかと、第一の溶液が同様にすべてのPythonのソリューションとして機能している間、最初のソリューションは、ファイル内にあることをZIPデータを要求します他のすべてのソリューションでは、Pythonスクリプトを作成する必要があります。

コマンドラインのワンライナーとして使用でき、STDINパイプを介して入力を取得し、新しくインストールされたmacOSですぐに使用できるPerlベースのソリューションを次に示します。

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

より適切にフォーマットされたPerlスクリプトは次のようになります。

use Compress::Raw::Zlib;
my $decompressor = new Compress::Raw::Zlib::Inflate();
my $output;
undef $/;
$decompressor->inflate(<>, $output);
print $output;

1

これを使用して、zlibで圧縮できます。

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

そして、これは収縮する:

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

4
与えunknown option '-z'Ubuntuの16.04と上OpenSSL 1.0.2g 1 Mar 2016
ティノ

2
Macでも同じエラー
K.-Michael Aye

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.