查找-exec cmd {} + vs | xargs


Answers:


107

速度差异不大。

但是您必须确保:

  1. 您的脚本不会假定文件名中没有文件空间,制表符等。第一个版本是安全的,第二个则不是。

  2. 您的脚本不会将以“ -” 开头的文件作为选项。

因此,您的代码应如下所示:

find . -exec cmd -option1 -option2 -- {} +

要么

find . -print0 | xargs -0 cmd -option1 -option2 --

第一个版本更短并且更容易编写,因为您可以忽略1,但是第二个版本更可移植且更安全,因为“ -exec cmd {} +”是GNU findutils中的一个相对较新的选项(自2005年以来,很多运行中的系统都没有它)最近越野车-exec cmd {} +您还可以从其他答案中看到很多人也不知道这个“ ”。


4
-print0也是GNU find(和GNU xargs)选项,许多非Linux系统都缺少该选项,因此可移植性参数无效。但是,仅使用-print并将xargs的-0保留非常可移植的。
2009年

7
关键是,如果没有-print0,则如果存在带有空格或制表符等的文件将不起作用。这可能是一个安全漏洞,就像存在诸如“ foo -o index.html”之类的文件名那样,-o将会被处理。作为一种选择。在空目录中尝试:“ touch-foo \ -o \ index.html; find。| xargs cat”。您会得到:“ cat:无效选项
-'o

2
他的示例是一个包含-的文件名。如果没有-print0,find将吐出./foo -o index.html。因此,也许以-开头不是什么大问题,但结果变化不大,并且在多用户系统上,如果您的脚本可读性强,则可以提供一种攻击媒介。
bobpaul 2012年

2
关于使我绊倒的事情的说明-使用exec将输出找到的结果xargs,似乎将等待搜索整个目录再写入stdout。如果您在大型目录上尝试此操作,但似乎xargs不起作用,建议耐心等待。
FarmerGedden

1
@Motivated Without -print0find返回以换行符分隔的文件名,但换行符也可以是文件名的一部分,从而使其变得模棱两可。字节0不能,所以它是一个安全的分隔符。是的- --当您不能控制它的参数时,即使不是总是严格要求或不安全的,将其添加到支持它的命令是一个好习惯。
Tometzky

7
find . | xargs cmd

效率更高(cmd与相比execcmd每次运行只运行一次),它运行的次数尽可能少。但是,如果文件名包含空格或时髦字符,则会遇到麻烦。

建议使用以下内容:

find . -print0 | xargs -0 cmd

即使文件名包含时髦的字符,这也将起作用(-print0使find打印以NUL终止的匹配,-0使xargs该格式生效)。


28
这不是“查找。-exec cmd {} \;”。但是“找到。-exec cmd {} +”。后者将不会一次运行一个文件。
2009年

2
请注意,xargs如果没有(或只有几个)匹配文件,cmd并且对于每个文件没有太多工作要做,则该方法实际上会大大降低速度。例如,在空目录中运行时,该xargs版本将花费至少两倍的时间,因为必须启动两个进程,而不仅仅是一个进程。(是的,在* nix上通常看不到这种差异,但是在循环中它可能很重要;或者,可以在Windows上尝试一下……)
SamB 2014年

2

Modern xargs的版本通常支持并行管道执行。

显然,在find … -exec 和 之间进行选择时,这可能是一个关键点。 … | xargs

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.