Answers:
速度差异不大。
但是您必须确保:
您的脚本不会假定文件名中没有文件空间,制表符等。第一个版本是安全的,第二个则不是。
您的脚本不会将以“ -
” 开头的文件作为选项。
因此,您的代码应如下所示:
find . -exec cmd -option1 -option2 -- {} +
要么
find . -print0 | xargs -0 cmd -option1 -option2 --
第一个版本更短并且更容易编写,因为您可以忽略1,但是第二个版本更可移植且更安全,因为“ -exec cmd {} +
”是GNU findutils中的一个相对较新的选项(自2005年以来,很多运行中的系统都没有它)最近是越野车。-exec cmd {} +
您还可以从其他答案中看到很多人也不知道这个“ ”。
exec
将输出找到的结果xargs
,似乎将等待搜索整个目录再写入stdout。如果您在大型目录上尝试此操作,但似乎xargs
不起作用,建议耐心等待。
-print0
find返回以换行符分隔的文件名,但换行符也可以是文件名的一部分,从而使其变得模棱两可。字节0不能,所以它是一个安全的分隔符。是的- --
当您不能控制它的参数时,即使不是总是严格要求或不安全的,将其添加到支持它的命令是一个好习惯。
find . | xargs cmd
效率更高(cmd
与相比exec
,cmd
每次运行只运行一次),它运行的次数尽可能少。但是,如果文件名包含空格或时髦字符,则会遇到麻烦。
建议使用以下内容:
find . -print0 | xargs -0 cmd
即使文件名包含时髦的字符,这也将起作用(-print0
使find
打印以NUL终止的匹配,-0
使xargs
该格式生效)。
xargs
如果没有(或只有几个)匹配文件,cmd
并且对于每个文件没有太多工作要做,则该方法实际上会大大降低速度。例如,在空目录中运行时,该xargs
版本将花费至少两倍的时间,因为必须启动两个进程,而不仅仅是一个进程。(是的,在* nix上通常看不到这种差异,但是在循环中它可能很重要;或者,可以在Windows上尝试一下……)