解压通过管道传入的文件

解压通过管道传入的文件

我可以让 unzip 或任何类似程序在标准输出上运行吗?情况是我正在下载一个 zip 文件,需要即时解压。

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

答案1

虽然 zip 文件实际上是一种容器格式,但如果文件可以轻松放入内存中,那么没有理由不能从管道 (stdin) 读取它。这是一个 Python 脚本,它将 zip 文件作为标准输入,并将内容提取到当前目录或指定目录(如果指定)。

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)

该脚本可以缩小为一行并创建为别名。

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

现在可以轻松解压 wget 的输出。

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

答案2

这不太可能像您预期的那样工作。Zip 不仅是一种压缩格式,也是一种容器格式。它将 tar 和 gzip.bzip2 的工作合并为一个。话虽如此,如果您的 zip 只有一个文件,您可以使用 unzip -p 将文件提取到 stdout。如果您有多个文件,则无法知道它们的开始和结束位置。

至于从 stdin 读取,unzip 手册页有这样一句话:

目前尚不支持从标准输入读取的档案,除非使用 funzip(然后只能提取档案的第一个成员)。

您可能会因为 funzip 而获得一些好运。

答案3

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

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

但是,bsdtar默认情况下没有安装,因此我无法funzip使用它。

答案4

您想要做的是,让 makeunzip将压缩文件作为其标准输入而不是作为参数。这通常很容易通过带有参数的工具来支持gziptar-标准unzip并没有这样做(尽管它确实支持提取到管道)。然而,一切还没有丢失……

看着趣味压缩手册页。

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

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

这很符合大多数 Linux 档案通常经过 TAR 处理然后以某种方式(gzip、bzip 等)压缩的想法。如果您有tar.ZIP.


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

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

然而,目前还没有看到这样的更新。我怀疑马克认为这没有必要,因为其他存档方法可以轻松地与 TAR 配合使用。

相关内容