我想下载一个tar.gz
存档,将其解压缩并在一个带有bash脚本的命令中将其压缩为zip
文件。原因是与临时文件无关。
我使用的代码:
curl -L "someURL" | tar xOz --strip-components=1 | zip -@ test.zip
向STDOUT提供了大量输出,因此我猜zip
不接受管道。
也许我在这里遗漏了一些东西,但是zip的手册页并没有给我提供比使用-@
或-
更多的信息,也没有互联网。
答案 0 :(得分:3)
zip
的联机帮助页(至少在我的系统上)说:
如果文件列表指定为 - @ [Not on MacOS],zip将从标准输入而不是命令行获取输入文件列表。例如,
zip -@ foo
将在foo.zip中的stdin上每行列出一个文件。
tar
-O, --to-stdout
将文件提取到标准输出。
简而言之:
tar -O
可以在一个长流中将文件(但不是其名称)输出到stdout
。但是zip
需要stdin
上的文件名列表。所以这不会起作用。并且很难看到如何使它工作,因为bash管道只是非结构化的字符串,但是要将信息从tar传输到zip,你需要添加一些结构,即使它是最小的:
[filename][filedata][filename][filedata]...
发件人(tar
)和接收者(zip
)必须就该结构的格式达成一致。哪个不会发生。
但是,您可以使用除命令行实用程序之外的tar
和zip
接口。例如,如果安装了python,则以下内容应该有效:
#!/usr/bin/python
import sys
import tarfile
import zipfile
tarf = tarfile.open(sys.argv[1], "r:*")
zipf = zipfile.ZipFile(sys.argv[2], "w", zipfile.ZIP_DEFLATED)
for m in tarf:
if m.isreg():
zipf.writestr(m.path, tarf.extractfile(m).read())
(需要进行大量错误检查。如上所述,它只会在出现任何错误时崩溃。)
你可以把它变成一个“非常长的”一个shell,虽然我个人只是使用上面的python脚本。
python -c "$(printf %s \
'import sys;import tarfile;import zipfile;' \
'T=tarfile.open(sys.argv[1],"r:*")' \
'Z=zipfile.ZipFile(sys.argv[2],"w",zipfile.ZIP_DEFLATED);' \
'[Z.writestr(m.path,T.extractfile(m).read()) for m in T if m.isreg()]')" \
input.tar output.zip
(如果你想从curl管道进入,请使用/dev/stdin
作为输入文件。我认为会避免Python试图将stdin
解释为UTF- 8流。)
答案 1 :(得分:2)
tar将把所有文件数据发送到stdout(但没有文件名)。
zip可能不会对此产生任何影响(除非在单个zip文件中创建所有文件内容的巨大拉链,我无法想象你想要那样)。 / p>
如果要创建文件的zip存档,则需要将文件解压缩到磁盘。
我打算说你可以循环遍历tarball中的条目(按名称)并将每个条目提取到管道(尽管就扫描所需的次数而言,这将是非常昂贵的。 tarball)但我实际上并没有看到,至少在这里有zip的手册页,有一种方法可以通过标准输入来压缩压缩数据。它似乎只是采用文件名。