DEFLATEアルゴリズムのコマンドラインラッパーを探しています。
DEFLATEを使用して圧縮されたファイル(git blob)があり、それを解凍したい。 gzipコマンドには、gzip形式ではなく、DEFLATEアルゴリズムを直接使用するオプションがないようです。
理想的には、これを行うことができる標準のUnix/Linuxツールを探しています。
編集:これは私の問題のためにgzipを使用しようとしたときに私が得る出力です:
$ cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip
gzip: stdin: not in gzip format
UPDATE:Mark Adlerは、git blobは生のDEFLATEストリームではなく、zlibストリームであると指摘しました。これらは、いくつかのLinuxディストリビューションにあらかじめパッケージ化されているpigz
ツールによって展開できます。
$ cat foo.txt
file foo.txt!
$ git ls-files -s foo.txt
100644 7a79fc625cac65001fb127f468847ab93b5f8b19 0 foo.txt
$ pigz -d < .git/objects/7a/79fc625cac65001fb127f468847ab93b5f8b19
blob 14file foo.txt!
歴史的な理由で保存されている私の元の答え:
Marc van Kempenが言及した Wikipediaの記事 のヒントを理解していれば、 puff.c
from zlib 直接。
これは小さな例です:
#include <assert.h>
#include <string.h>
#include "puff.h"
int main( int argc, char **argv ) {
unsigned char dest[ 5 ];
unsigned long destlen = 4;
const unsigned char *source = "\x4B\x2C\x4E\x49\x03\x00";
unsigned long sourcelen = 6;
assert( puff( dest, &destlen, source, &sourcelen ) == 0 );
dest[ 4 ] = '\0';
assert( strcmp( dest, "asdf" ) == 0 );
}
次のようなものは、「$ type $ length\0」ヘッダーを含む生のコンテンツを印刷します。
Perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' \
< .git/objects/27/de0a1dd5a89a94990618632967a1c86a82d577
これを行うには、OpenSSLコマンドラインツールを使用します。
openssl zlib -d < $IN > $OUT
残念ながら、少なくともUbuntuでは、zlib
サブコマンドはデフォルトのビルド構成で無効になっています(--no-zlib
--no-zlib-dynamic
)、それを使用するにはソースからopenssl
をコンパイルする必要があります。ただし、たとえばArchではデフォルトで有効になっています。
編集:zlib
コマンドもArchではサポートされなくなったようです。この答えはもう役に立たないかもしれません:(
Pythonicワンライナー:
$> python -c "import zlib,sys;print \
repr(zlib.decompress(sys.stdin.read()))" < $IN
次のように、zlib-flateを使用できます。
cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 \
| zlib-flate -uncompress; echo
私のマシンにはデフォルトでありますが、インストールする必要がある場合はqpdf - tools for and transforming and inspecting PDF files
の一部です。
出力をそのように読みやすくするため、コマンドの最後にecho
をポップしました。
次のコマンドを試してください。
printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip
外部ツールは必要ありません。
ソース: NIXでzlibデータを解凍する方法? UNIX SEで
Ruby one-liner(cd .git /最初に任意のオブジェクトへのパスを識別する):
Ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208
私はこれに対して良い解決策がないことにうんざりしたので、NPMに何かを付けました:
https://github.com/jezell/zlibber
これで、パイプでinflate/deflateコマンドを実行できます。
Pythonでコミットオブジェクトを壊す例は次のとおりです。
$ git show
commit 0972d7651ff85bedf464fba868c2ef434543916a
# all the junk in my commit...
$ python
>>> import zlib
>>> file = open(".git/objects/09/72d7651ff85bedf464fba868c2ef434543916a")
>>> data = file.read()
>>> print data
# binary garbage
>>> unzipped_data = zlib.decompress(data)
>>> print unzipped_data
# all the junk in my commit!
表示される内容は、コマンドがヘッダーを出力しないことを除いて、「git cat-file -p [hash]」の出力とほぼ同じです(「commit」の後にコンテンツのサイズとヌルバイトが続きます)。
マーク・アドラーは私たちを念頭に置いており、これを行う方法の例を書いたように見えます: http://www.zlib.net/zpipe.c
gcc -lz
とzlibヘッダーのみがインストールされた状態でコンパイルします。 gitスタッフで作業しながら、結果のバイナリを/usr/local/bin/zpipe
にコピーしました。
gitオブジェクトはzlib
ではなくgzip
によって圧縮されるため、zlib
を使用して圧縮解除するか、gitコマンド、つまりgit cat-file -p <SHA1>
、コンテンツを印刷します。
// save this as deflate.go
package main
import (
"compress/zlib"
"io"
"os"
"flag"
)
var infile = flag.String("f", "", "infile")
func main() {
flag.Parse()
file, _ := os.Open(*infile)
r, err := zlib.NewReader(file)
if err != nil {
panic(err)
}
io.Copy(os.Stdout, r)
r.Close()
}
$ go build deflate.go
$ ./deflate -f .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7
http://en.wikipedia.org/wiki/DEFLATE#Encoder_implementations を参照してください
動作するはずのgzipを含む、多くのソフトウェア実装がリストされています。ファイルに対してgzipを実行してみましたか?フォーマットを自動的に認識しませんか?
DEFLATEを使用して圧縮されていることがわかりますか?ファイルを圧縮するためにどのツールが使用されましたか?
この質問は、インストールしたばかりの-text
クライアントの新しいバージョンにあるhadoop dfs
ユーティリティのバグの回避策を探しているときに見つかりました。 -text
ユーティリティはcat
と同様に機能しますが、読み取られるファイルが圧縮されている場合は、透過的に圧縮解除され、プレーンテキストが出力されます(そのため)。
すでに投稿された回答は間違いなく役立ちましたが、Hadoopサイズのデータを処理する際に1つ問題があります-解凍する前にすべてをメモリに読み込みます。
そのため、上記のPerl
およびPython
の回答のバリエーションがあり、その制限はありません。
Python:
hadoop fs -cat /path/to/example.deflate |
python -c 'import zlib,sys;map(lambda b:sys.stdout.write(zlib.decompress(b)),iter(lambda:sys.stdin.read(4096),""))'
Perl:
hadoop fs -cat /path/to/example.deflate |
Perl -MCompress::Zlib -e 'print uncompress($buf) while sysread(STDIN,$buf,4096)'
-cat
の代わりに-text
サブコマンドを使用していることに注意してください。これは、バグを修正した後、私の回避策が壊れないようにするためです。 pythonバージョンの読みやすさについておApび申し上げます。
gitオブジェクトはzlibストリームです(raw deflateではありません)。 pigz は、-dz
オプション。
なぜgitのツールを使用してデータにアクセスしないのですか?これにより、任意のgitオブジェクトを読み取ることができるはずです。
git show --pretty=raw <object SHA-1>
const zlib = require("zlib");
const adler32 = require("adler32");
const data = "hello world~!";
const chksum = adler32.sum(new Buffer(data)).toString(16);
console.log("789c",zlib.deflateRawSync(data).toString("hex"),chksum);
// or
console.log(zlib.deflateSync(data).toString("hex"));
pigz できる:
apt-get install pigz
unpigz -c .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7
コレクションに追加するために、deflate/inflate/raw deflate/raw inflate用のPerlワンライナーがあります。
デフレート
Perl -MIO::Compress::Deflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Compress::Deflate::deflate(\$in, \$out); print $out;'
インフレ
Perl -MIO::Uncompress::Inflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Uncompress::Inflate::inflate(\$in, \$out); print $out;'
生の収縮
Perl -MIO::Compress::RawDeflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Compress::RawDeflate::rawdeflate(\$in, \$out); print $out;'
生膨張
Perl -MIO::Uncompress::RawInflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Uncompress::RawInflate::rawinflate(\$in, \$out); print $out;'