题
我正在寻找用于放气算法的命令行包装器。
我有一个使用Deflate压缩的文件(git blob),我想取消压缩。 GZIP命令似乎没有一个可以直接使用Deflate算法而不是GZIP格式的选项。
理想情况下,我正在寻找可以执行此操作的标准UNIX/Linux工具。
编辑:这是我尝试使用GZIP来解决我的问题时获得的输出:
$ cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip
gzip: stdin: not in gzip format
解决方案
更新: 马克·阿德勒(Mark Adler)指出,Git Blobs不是原始的Deflate流,而是Zlib流。这些可以被 pigz
工具,该工具预先包装在几个Linux分布中:
$ 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)提到的,您可以使用 puff.c
从 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
也不再在拱门上支持命令。这个答案可能不再有用:(
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
不需要外部工具。
来源: 如何在UNIX中取消压缩ZLIB数据? 在Unix SE
这是一个红宝石单线(CD .git/ first,并确定任何对象的路径):
ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208
这是打破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',然后是内容的大小和null字节的大小)。
看来马克·阿德勒(Mark Adler)牢记了我们,并写了一个关于如何做到这一点的示例: http://www.zlib.net/zpipe.c
它无非是编译 gcc -lz
并安装了ZLIB标头。我将结果二进制复制到我的 /usr/local/bin/zpipe
在使用git的东西时。
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压缩了?什么工具用于压缩文件?
您为什么不只是使用Git的工具访问数据?这应该能够读取任何git对象:
git show --pretty=raw <object SHA-1>
我发现这个问题正在寻找一个带有错误的工作 -text
新版本的实用程序 hadoop dfs
我刚刚安装的客户。这 -text
公用事业工作 cat
, ,除非被读取的文件被压缩,否则它会透明地解压缩并输出普通文本(因此名称)。
已经发布的答案绝对有用,但是在处理Hadoop大小的数据时,其中一些人有一个问题 - 他们在解压缩之前将所有内容都读为内存。
所以,这是我关于 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),""))'
佩尔:
hadoop fs -cat /path/to/example.deflate |
perl -MCompress::Zlib -e 'print uncompress($buf) while sysread(STDIN,$buf,4096)'
注意使用 -cat
子命令,而不是 -text
. 。这样一来,我的工作就不会在他们修复错误后破裂。对于Python版本的可读性表示歉意。
GIT对象是Zlib流(不是原始的气流)。 猪 将压缩那些 -dz
选项。
猪 可以做到:
apt-get install pigz
unpigz -c .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7
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"));
为了添加该集合,这里是用于放气/膨胀/原始气气/原始膨胀的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;'
原始DEFLATE
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;'