请考虑以下代码段:
tar -Oxvf archive.tgz | grep something
或者这个:
tar tf archive.tgz > /tmp/x && tar -Oxvf archive.tgz -T /tmp/x | grep something
与此相对:
tar tf archive.tgz | xargs -I{} tar -Oxvf archive.tgz {} | grep something
前两个片段非常快且相似,而第三个片段慢了约40倍(这个索引相对于我猜的存档内容)。那是为什么?
答案 0 :(得分:1)
我有点不确定你想用你的例子做什么。我不明白第一个例子中的第一个管道应该实现什么,因为没有使用通过管道连接到第二个tar的输出。 &&
似乎是加入这两个命令的更好方法(仅在第一个命令成功时才执行第二个命令)。除此之外,如果您使用完整的文件列表进行提取(并且仅用于该任务),就像在您的示例中一样,没有必要在创建它时花费单独的tar运行,因为默认情况下tar会除非另有说明,否则提取所有文件。
就速度而言 - 管道接收端的焦油没有特殊的方法可以区分输入它是否来自另一个焦油以进行优化。但是,在两个tar命令的情况下,第一个将立即启动其输出,因此第二个tar可以开始运行,而xargs将首先收集所有数据,然后启动其输出和提供焦油安排在它之后运行。
如果您正在寻找一种从tar存档中仅提取文件子集的快速方法,并希望按文件名选择,我建议使用star,它具有内置查找命令。< / p>
答案 1 :(得分:1)
这里的关键是你在xargs中使用-I{}
。该手册页说:
-I replace-str
将initial-arguments中出现的replace-str替换为从标准输入读取的名称。此外,不带引号的空白不会 终止输入项目;相反,分隔符是换行符。 意味着-x和-L 1 。
隐含的-L 1
使xargs
在归档中的每个文件中运行tar -Oxvf archive.tgz {}
一次,而不是运行tar一次以提取xargs的stdin上列出的所有文件。
差异的简化示例:
$ (echo foo; echo bar)|xargs -I{} echo {}
foo
bar
$ (echo foo; echo bar)|xargs echo
foo bar
修正:
tar tf archive.tgz | xargs tar -Oxvf archive.tgz | grep something
但是请注意,如果给xargs -I{}
的文件名不是tar文件顺序(即xargs
的顺序,那么它的输出将与使用tar t
获得的输出不同。 1}}列出它们)。 xargs -I{}
版本将按照您提供给xargs的顺序输出文件,而此版本将以tar文件顺序输出它们。