解压缩通过pipe道飞入的文件

我可以在标准输出上使用解压缩或类似的程序吗? 情况是我正在下载一个zip文件,这应该是在飞行中解压缩。

相关问题: 如何在bash中将下载的文件传输到标准输出?

    虽然zip文件实际上是一个容器格式,但是如果文件可以轻松地放入内存中,没有理由不能将其视为stream。 这是一个Python脚本,它将一个zip文件作为标准input,并将其内容提取到当前目录或指定的目录中。

    import zipfile import sys import StringIO data = StringIO.StringIO(sys.stdin.read()) z = zipfile.ZipFile(data) dest = sys.argv[1] if len(sys.argv) == 2 else '.' z.extractall(dest) 

    这个脚本可以缩小到一行,并创build一个别名。

     alias unzip-stream="python -c \"import zipfile,sys,StringIO;zipfile.ZipFile(StringIO.StringIO(sys.stdin.read())).extractall(sys.argv[1] if len(sys.argv) == 2 else '.')\"" 

    现在轻松地解压缩stream。

     wget http://your.domain.com/your/file.zip -O - | unzip-stream target_dir 

    这是不太可能工作如何你期望。 Zip不仅是一种压缩格式,也是一种容器格式。 它将tar和gzip.bzip2的作业合并为一个。 话虽如此,如果您的zip文件只有一个文件,您可以使用unzip -p将文件解压缩到stdout。 如果你有一个以上的文件,你不能告诉他们在哪里开始和停止。

    至于从标准input读取,解压缩手册页有这样一句话:

    从标准input中读取的档案目前还不支持,除了funzip(然后只有档案的第一个成员可以被提取)。

    用funzip可能会有一些运气。

    你想要做的是, unzip标准inputZIP unzip文件,而不是作为一个参数。 这通常可以通过带有-参数的gziptar类工具轻松支持。 但标准的unzip不会这样做(尽pipe它支持抽取pipe道)。 但是,一切都不会丢失…

    看看funzip手册页。

    没有文件参数的funzip充当filter; 也就是说,它假定一个ZIP压缩文件(或一个gzip文件)被传送到标准input中,并且将第一个成员从压缩文件中提取到标准输出。 当stdin来自一个tty设备时,funzip假设这不是一个(二进制)压缩数据stream,而是显示一个简短的帮助文本。 如果有文件参数,则从指定的文件而不是标准input读取input。

    鉴于单一成员提取的限制,funzip与辅助归档程序(如tar(1))结合使用最为有用。 以下部分包含一个示例,说明在将磁盘备份到磁带的情况下的使用情况。

    这与大多数Linux档案通常被TARed然后以某种方式进行ZIP压缩(gzip,bzip等)的想法相符合。 如果你有一个tar.ZIP这将适用于你。


    值得注意的是, funzip是由Info-ZIP原作者Mark Adler编写的。 他在funzip手册中写道,

     this functionality should be incorporated into unzip itself (future release). 

    然而,周围没有看到这样的更新。 我怀疑马克认为没有必要,因为其他归档方法可以很容易地与TAR合作。

    Info-Zip是最常见的OSS实现,这是不可能的。 更重要的是,由于ZIP压缩文件的构造,不推荐使用。

    如果格式的改变对你是可行的,那么考虑使用tar(1)来代替。 对stream式input/输出非常满意,事实上,预计它是默认的。

    另外,通过指定“ – ”作为文件名,通常可以知道应用程序是否期望stream式input/输出。 你可以想象,Info-Zip并不把它当作一个有效的参数。

    我喜欢使用curl,因为它是默认安装的( -L经常发生redirect需要):

     curl -L http://example.com/file.zip | bsdtar -xvf - -C /path/to/directory/ 

    但是,默认情况下, bsdtar没有安装,我无法获得funzip的工作。

    在zsh中,您可以执行以下操作:

     unzip =( curl http://example.com/someZipFile.zip )