Shell `tar通过xargs降低性能` 请考虑这个片段:

Shell `tar通过xargs降低性能` 请考虑这个片段:,shell,tar,xargs,Shell,Tar,Xargs,tar-Oxvf archive.tgz | grep something 或者这个: tar tf archive.tgz>/tmp/x&&tar-Oxvf archive.tgz-T/tmp/x | grep something 与此相比: tartfarchive.tgz|xargs-I{}tar-Oxvf archive.tgz{}| grep something 前两个代码段速度非常快且相似,而第三个代码段速度慢约40倍(我想这个索引是相对于归档内容的)。这是为什么?我有点不确定你想通

tar-Oxvf archive.tgz | grep something

或者这个:

tar tf archive.tgz>/tmp/x&&tar-Oxvf archive.tgz-T/tmp/x | grep something

与此相比:

tartfarchive.tgz|xargs-I{}tar-Oxvf archive.tgz{}| grep something


前两个代码段速度非常快且相似,而第三个代码段速度慢约40倍(我想这个索引是相对于归档内容的)。这是为什么?

我有点不确定你想通过你的例子获得什么。我不明白第一个示例中的第一个管道应该实现什么,因为没有使用通过管道传输到第二个tar的输出。
&&
似乎是连接两个命令的更好方法(仅当第一个命令成功时才执行第二个命令)。除此之外,如果您使用完整的文件列表进行提取(并且仅用于该任务),如您的示例中所示,则无需花费单独的tar运行来创建它,因为tar默认情况下将提取所有文件,除非另有说明

就速度而言——管道接收端的tar没有特殊的方法来区分它获得的输入是否来自另一个tar以进行优化。但真正有区别的是,在两个tar命令的情况下,第一个命令将立即启动其输出,因此第二个tar可以开始运行,而xargs将首先收集所有数据,然后启动其输出并向安排在其之后运行的tar提供数据


如果您正在寻找一种从tar归档文件中只提取文件子集的快速方法,并且希望按文件名进行选择,我建议使用,它有一个内置的find命令。

这里的关键是在xargs中使用
-I{}
。手册页上说:

   -I replace-str
用从标准输入读取的名称替换初始参数中出现的Replace str。此外,不带引号的空格不适用 终止输入项;相反,分隔符是换行符。 表示-x和-L 1

隐含的
-l1
使
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
的文件名不是tar文件顺序(即与
tart
列出它们的顺序相同),则此输出将与使用
xargs-I{}
得到的结果不同。
xargs-I{}
版本将按照您提供给xargs的顺序输出文件,而此版本将按照tar文件顺序输出文件。

使用
-T
开关时,
tar
根据自己的规则一次读取列表并提取文件(即,它不是按
/tmp/x
文件列表中的顺序提取,而是按压缩顺序提取),而当使用
xargs
时,会从顺序执行中扣除惩罚。即使这变为真,它也太慢了,您说得对,我添加了
&
。我的问题是,我的文件以未排序的顺序存储在tar归档中-这就是它们的创建方式-我需要输出(grep)遍历tar归档内容,但按排序。结果表明,
tar
提取文件的顺序与存储文件的顺序不同,毕竟
tar
被设计为磁带归档程序。如前所述,
tar
不尊重文件列表中所指文件的顺序(-t开关)或者-它在一次过程中提取,如果文件在列表中的任何位置,则列出它extracts@theta它也不尊重多个命令行参数的顺序,它们的行为就像
-t
。问题是
xargs-I{}
(参见我的答案)好的。这当然是对所问问题的正确回答,但我想指出的是,这种方式
tar tf archive.tgz | sort | xargs tar-Oxvf archive.tgz
在输出时不会对归档文件进行排序,而
tar tf archive.tgz | sort | xargs-I{}tar Oxvf archive.tgz}
将进行排序,并根据您解释的原因接受时间惩罚。Thanks@theta要点-我实际上考虑过在其中添加一个关于潜在顺序变化的注释,但决定反对,因为
tar tf
将始终生成与
tar x
提取它们相同的顺序。事后看来,这是一个错误的决定,因为它是这显然是一个简化的例子。