【发布时间】:2018-04-24 10:30:17
【问题描述】:
对于非常大的文件集,应该使用哪个更有效?
find . -exec cmd {} +
或
find . | xargs cmd
(假设文件名中没有有趣的字符)
【问题讨论】:
标签: linux unix command-line find
对于非常大的文件集,应该使用哪个更有效?
find . -exec cmd {} +
或
find . | xargs cmd
(假设文件名中没有有趣的字符)
【问题讨论】:
标签: linux unix command-line find
速度差异将是微不足道的。
但你必须确保:
您的脚本不会假定没有 文件中将有空格、制表符等 文件名;第一个版本是 安全,第二个不安全。
您的脚本不会将以“-”开头的文件作为选项。
所以你的代码应该是这样的:
find . -exec cmd -option1 -option2 -- {} +
或
find . -print0 | xargs -0 cmd -option1 -option2 --
第一个版本更短更容易写,因为你可以忽略 1,但是
第二个版本更加便携和安全,因为“-exec cmd {} +”是 GNU findutils 中一个相对较新的选项(自 2005 年以来,许多正在运行的系统还没有它),它是 buggy recently。也有很多人不知道这个“-exec cmd {} +”,正如您从其他答案中看到的那样。
【讨论】:
exec 将在找到结果时输出结果,而 xargs 似乎会等到整个目录被搜索到后再写入标准输出.如果您在大型目录中尝试此操作,并且似乎 xargs 不起作用,建议您耐心等待。
-print0 find 返回用换行符分隔的文件名,但换行符也可以是文件名的一部分,使其不明确。字节 0 不能,所以它是一个安全的分隔符。是的 - 当您无法控制其参数时,将-- 添加到支持它的命令中是一个好习惯,即使并非总是严格要求或不安全。
find . | xargs cmd
效率更高(它运行cmd 的次数越少越好,不像exec,它为每场比赛运行一次cmd)。但是,如果文件名包含空格或时髦字符,您将遇到麻烦。
建议使用以下:
find . -print0 | xargs -0 cmd
即使文件名包含时髦字符,这也可以工作(-print0 使 find 打印 NUL 终止匹配,-0 使 xargs 期望这种格式。)
【讨论】:
cmd 对每个文件没有太多工作要做,xargs 方法实际上会慢得多。例如,当在空目录中运行时,xargs 版本将花费至少两倍的时间,因为必须启动两个进程而不是只启动一个。 (是的,这种差异在 *nix 上通常是难以察觉的,但在循环中它可能很重要;或者,在 Windows 上尝试一段时间......)
现代xargs 的版本通常支持并行管道执行。
显然,在选择
find … -exec
和
… | xargs
【讨论】: