2010-07-05 222 views
68

我正在寻找DEFLATE算法的命令行包装器。Deflate命令行工具

我有一个使用DEFLATE压缩的文件(git blob),我想解压缩它。 gzip命令似乎没有直接使用DEFLATE算法的选项,而不是gzip格式。

理想情况下,我正在寻找一个标准的Unix/Linux工具,可以做到这一点。

编辑:这是输出试图用gzip我的问题时,我得到:

$ cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip 

gzip: stdin: not in gzip format 

回答

5

更新:马克阿德勒指出,git blob不是原始的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! 

我原来的答复,保存历史原因:

如果我的理解中提到的Wikipedia article提示通过Marc van Kempen,您可以直接使用zlibpuff.c

这是一个小例子:

#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); 
} 
+3

是的,我看着那个。但我肯定会更喜欢通常打包的工具。 – 2010-07-05 10:10:53

+0

好的,现在用一个最简单的例子做了一个很晚的编辑。 – mkluwe 2016-05-10 19:20:22

+0

这不起作用。 git blob是zlib流,不是原始的deflate。此解决方案适用于原始减压。粉扑不处理zlib标题和预告片。如果你想要一个实用程序,你可以使用[pigz](http://zlib.net/pigz),它将用'-dz'选项解压缩zlib格式,并使用'-z'生成zlib格式。 。 – 2017-11-05 15:41:05

1

http://en.wikipedia.org/wiki/DEFLATE#Encoder_implementations

它列出了一些软件实现,包括gzip的,所以应该工作。你是否尝试在文件上运行gzip?它不会自动识别格式吗?

你怎么知道它是用DEFLATE压缩的?用什么工具压缩文件?

+0

看到这个页面的底部:http://progit.org/book/ch9-2.html Gzip确实实现了DEFLATE,但它似乎并不像你可以直接应用算法。 Gzip预计数据将采用gzip格式(这会在DEFLATE的数据中添加一堆头文件)。 (我刚刚编辑我的文章,包括gunzip的输出) – 2010-07-05 10:07:07

+2

好吧,所以数据使用zlib库进行压缩,那么它也有理由使用zlib解压缩!你可以尝试使用ruby,perl或其他绑定来制作一个简单的deflate脚本。或者如果你不害怕在编译ac程序时尝试你的手,试试这个: http://www.zlib.net/zlib_how.html – 2010-07-05 10:20:56

+0

NB我只是试过了,zpipe.c工作在git对象上,编译与 'GCC -o zpipe zpipe.c -I /路径/到/ zlib.h -L /路径/到/ ZLIB -lz' 使用: ./zpipe -d 2010-07-05 12:09:18

0

你为什么不只是使用Git的工具来访问数据?这应该能够读取任何git的对象:

git show --pretty=raw <object SHA-1> 
+3

我正在准备一个小小的git-workshop,我很快就会放弃。其中一个例子涉及到手动添加'git add'。 使用git解压缩blob本身没有意义,因为我想显示underlay的功能。我可能最终会使用ruby或perl,但我希望能坚持一个简单的bash oneliner。 – 2010-07-05 10:58:26

+2

或'git cat-file -p c0fb67ab3fda7909000da003f4b2ce50a53f43e7' – 2010-07-05 12:51:49

+0

@igorw:只要对象在树中。关于在'lost + found'中找到一些git-objects的知识(在fsck.ext4将它们放在那里之后)非常方便... – akira 2011-11-30 12:27:22

46

像下面将打印的原始内容,其中包括“$类型$长度\ 0”头:

perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' \ 
    < .git/objects/27/de0a1dd5a89a94990618632967a1c86a82d577 
+0

[错误]在没有'78'标记和最终crc的* raw * deflate流中输出为零并退出代码。 – ulidtko 2017-04-24 10:50:37

+0

对于我来说也适用于使用zlib在'C'中直接压缩的任何数据,所以非常棒的答案。和往常一样:最终,大多数世界问题都可以通过PERL来解决;) – Mecki 2017-10-11 13:22:33

9

下面是一个例子砸开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的猫文件-p [散列]”输出,但命令不打印头(”提交'后跟大小内容和一个空字节)。

+4

根据操作系统的不同,您可能希望为“open”添加“rb”开关,例如:file = open(“。 git/objects/09/72d7651ff85bedf464fba868c2ef434543916a“,”rb“)' – 2011-11-19 11:16:23

+3

+1来解释标题的格式。 – ntc2 2014-01-23 04:14:04

38

Python的单行:

$> python -c "import zlib,sys;print \ 
      repr(zlib.decompress(sys.stdin.read()))" < $IN 
+0

'repr(...)'似乎将所有内容都包含在引号(''...'')中,所以我必须将其删除(解压缩zlib压缩的JSON文件)。 – 2014-04-09 11:37:48

+0

这精美的作品! – 2015-03-13 05:01:58

+0

其实它的'蟒蛇-c “进口zlib的,SYS;打印(zlib.decompress(sys.stdin.buffer.read())解码( 'utf-8'))”<$ IN',如果你期望的UTF8文件实例在Python 3 – 2017-01-30 19:11:50

14

这里是红宝石单行(CD的.git /第一和识别路径的任何对象):

ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208 
+0

剥去[BLOB大小]报头 '红宝石-rzlib -e“打印的zlib :: Inflate.inflate($ stdin.read).split( “\ X00”)[1 ..- 1] 。加入 yachi 2015-04-02 02:16:20

6

git的目的是通过zlib压缩而不是gzip,因此要么使用zlib进行解压缩,要么使用git命令即git cat-file -p <SHA1>来打印内容。

+3

如[杰克指出上述(http://stackoverflow.com/a/6539072/470844)的GIT中'猫文件输出-p '*不是* .git/objects/的zlib解压缩的完整内容。所不同的是,如果你想实现一个Git提交哈希运算键... – ntc2 2014-01-23 04:15:59

+0

的-p漂亮的打印选项是,虽然当你想了解对象的内容优势。用pigz解压缩树对象不会给你一个可读的结果。 – Vortexfive 2018-03-01 21:34:58

6

看起来像马克·阿德勒已经让我们记住,写的一个例子,是如何与执行此操作:http://www.zlib.net/zpipe.c

它编译无非就是gcc -lz并安装zlib的头。我使用git工具将生成的二进制文件复制到我的/usr/local/bin/zpipe

8

我厌倦了没有这个很好的解决,所以我把东西在NPM:

https://github.com/jezell/zlibber

现在可以只是管道膨胀/收缩命令。

+0

你如何使用这个软件包? – RHPT 2016-03-25 15:05:36

+0

@RPT在Windows上,执行“type #### | inflate”,其中####是对象的校验和。 – mhenry1384 2016-10-03 01:22:43

24

您可以使用zlib-flate,像这样:

cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 \ 
    | zlib-flate -uncompress; echo 

它的存在,在默认情况下我的机器上,但它的qpdf - tools for and transforming and inspecting PDF files一部分,如果你需要安装它。

我在命令的末尾弹出了一个echo,因为这样更容易读取输出。

+1

它在Ubuntu 14.04上没有任何安装 – Ricardo 2015-02-11 20:08:24

+1

无需cat:zlib-flate -uncompress <.git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 – 2017-05-15 20:26:49

42

您可以使用OpenSSL命令行工具做到这一点:

openssl zlib -d < $IN > $OUT 

不幸的是,至少在Ubuntu中,zlib子命令默认生成配置(--no-zlib--no-zlib-dynamic)禁用,所以你需要编译openssl从源码使用它。但是,例如,它在Arch上默认启用。

编辑:看起来像拱门上不再支持zlib命令。这个答案可能不适用了:(

+10

请注意,'zlib'子命令(以及'如果你的openssl的内部版本配置了默认选项,包括'--no-zlib'和'--no-zlib-dynamic',那么* not *是可用的。所以这个答案只适用于你的openssl是用从其中一个配置选项中删除的'no-'前缀编译的。您可以通过在'openssl version -f' – Hercynium 2014-05-13 16:02:40

+0

@Hercynium的输出中查找'-DZLIB'来感谢!特别是对于Ubuntu 14.04,我的情况是这样的:( – 2014-12-14 09:43:52

+0

在我的fedora服务器上工作正常 – fuzzyTew 2016-12-23 17:54:28

1

我发现这个问题有一个bug寻找与在hadoop dfs客户我刚安装的新版本-text实用的变通,该-text工具就像cat,除了如果正在读取的文件被压缩,它会透明地解压缩并输出纯文本(因此名称)。

已发布的答案肯定有帮助,但其中一些在处理Hadoop大小的数量时遇到了一个问题数据 - 它们在解压缩之前将所有内容读入内存中。

所以,这里是我对PerlPython回答上面的变化没有这样的限制:

的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。这是为了让我的解决方法在修复bug后不会中断。道歉为python版本的可读性。

17

试试下面的命令:需要

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip 

没有外部工具。

来源:How to uncompress zlib data in UNIX?在UNIX SE

+1

最终出现“文件意外结束”错误,但仍然是一个整齐的破解。 – Eric 2015-03-18 17:01:09

+2

只需添加一个gzip文件头。 – 2016-01-14 20:32:40

+1

这就是我发现它的地方 - 在我的'.bashrc'中添加了'zlipd()(printf“\ x1f \ x8b \ x08 \ x00 \ x00 \ x00 \ x00 \ x00”| cat - $ @ | gzip -dc)现在:) – 2016-05-04 06:05:32

5
// 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 
+0

在macOS 10.11上精美地工作,谢谢!我必须从[官方网站](https://golang.org/dl/)安装Go(我本来打算这么做),然后它运行得很好。你自己写了这个吗?对于意外的争论并不是很好。 :) – Wildcard 2016-10-02 02:55:42

0

pigz可以做到这一点:

apt-get install pigz 
unpigz -c .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 
0
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")); 
1

git的对象是zlib的流(不生放气) 。 pigz将使用-dz选项对其进行解压缩。