我想知道到底是什么{} \;和{} \+和| xargs ...做的。请通过解释进行澄清。
{} \;
{} \+
| xargs ...
下面的3条命令运行并输出相同的结果,但是第一个命令花费一些时间,格式也几乎没有什么不同。
find . -type f -exec file {} \; find . -type f -exec file {} \+ find . -type f | xargs file
这是因为第1个file命令针对来自该find命令的每个文件运行该命令。因此,基本上它的运行方式为:
file
find
file file1.txt file file2.txt
但是后2个-exec命令查找命令对所有文件运行一次file命令,如下所示:
-exec
file file1.txt file2.txt
然后,我运行以下命令,第一个在没有问题的情况下运行,但第二个给出错误消息。
find . -type f -iname '*.cpp' -exec mv {} ./test/ \; find . -type f -iname '*.cpp' -exec mv {} ./test/ \+ #gives error:find: missing argument to `-exec'
对于带有的命令{} \+,它会给我错误消息
find: missing argument to `-exec'
这是为什么?谁能解释我在做什么错?
该手册(或在线GNU手册)几乎说明了一切。
对于每个结果,command {}都会执行。出现的所有内容{}均替换为文件名。;以斜杠为前缀,以防止外壳解释它。
command {}
{}
;
每个结果都将附加command并执行。考虑到命令长度的限制,我猜想该命令可能会执行更多次,其中手册页支持我:
command
该命令的调用总数将远远少于匹配文件的数目。
请注意手册页中的以下引用:
命令行的构建与xargs构建命令行的方式几乎相同
这就是为什么在空格之间{}以及+除空格之外都不允许使用任何字符的原因。+make find检测到应将参数附加到命令,就像xargs。
+
xargs
幸运的是,的GNU实现mv可以接受目标目录作为参数,可以使用-t或较长的parameter --target。它的用法将是:
mv
-t
--target
mv -t target file1 file2 ...
您的find命令将变为:
find . -type f -iname '*.cpp' -exec mv -t ./test/ {} \+
从手册页:
-exec命令; 执行命令;如果返回0状态,则为true。以下所有要查找的参数都将被视为命令的参数,直到由’;’组成的参数为止 遇到。字符串“ {}”将替换为在命令参数中出现的所有处所正在处理的当前文件名,而不是仅在单独存在的参数中(如在某些版本的find中)。这两种构造都可能需要转义(以’'表示)或加引号,以防止它们被外壳扩展。有关使用- exec选项的示例,请参见示例部分。对于每个匹配的文件,指定的命令运行一次。该命令在起始目录中执行。-exec操作的使用不可避免地存在安全问题;您应该改用- execdir选项。 -exec命令{} + -exec操作的此变体在选定的文件上运行指定的命令,但是通过在末尾附加每个选定的文件名来构建命令行。该命令的调用总数将远远少于匹配文件的数目。命令行的构建与xargs构建命令行的方式几乎相同。该命令内仅允许一个{{}”实例。该命令在起始目录中执行。
-exec命令;
执行命令;如果返回0状态,则为true。以下所有要查找的参数都将被视为命令的参数,直到由’;’组成的参数为止 遇到。字符串“ {}”将替换为在命令参数中出现的所有处所正在处理的当前文件名,而不是仅在单独存在的参数中(如在某些版本的find中)。这两种构造都可能需要转义(以’'表示)或加引号,以防止它们被外壳扩展。有关使用- exec选项的示例,请参见示例部分。对于每个匹配的文件,指定的命令运行一次。该命令在起始目录中执行。-exec操作的使用不可避免地存在安全问题;您应该改用- execdir选项。
-exec命令{} +
-exec操作的此变体在选定的文件上运行指定的命令,但是通过在末尾附加每个选定的文件名来构建命令行。该命令的调用总数将远远少于匹配文件的数目。命令行的构建与xargs构建命令行的方式几乎相同。该命令内仅允许一个{{}”实例。该命令在起始目录中执行。