在find中使用分号(;)vs plus(+)和exec

时间:2011-05-21 23:49:54

标签: find

为什么使用

之间的输出存在差异
find . -exec ls '{}' \+

find . -exec ls '{}' \;

我得到了:

$ find . -exec ls  \{\} \+
./file1  ./file2

.:
file1  file2  testdir1

./testdir1:
testdir2

./testdir1/testdir2:


$ find . -exec ls  \{\} \;
file1  file2  testdir1
testdir2
./file2
./file1

6 个答案:

答案 0 :(得分:202)

这可能最好用一个例子来说明。假设find出现了这些文件:

file1
file2
file3

-exec与分号(find . -exec ls '{}' \;)一起使用,将执行

ls file1
ls file2
ls file3

但是如果你使用加号(find . -exec ls '{}' \+),尽可能多的文件名作为参数传递给单个命令:

ls file1 file2 file3

文件名的数量仅受系统最大命令行长度的限制。如果命令超过此长度,则将多次调用该命令。

答案 1 :(得分:31)

到目前为止,所有答案都是正确的。我提供这个更清楚(对我来说)使用echo而不是ls描述的行为:

使用分号,每个文件(或其他文件系统对象)都会调用一次echo命令:

$ find . -name 'test*' -exec echo {} \;
./test.c
./test.cpp
./test.new
./test.php
./test.py
./test.sh

使用加号,命令echo仅被调用一次。找到的每个文件都作为参数传入。

$ find . -name 'test*' -exec echo {} \+
./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh

如果find出现大量结果,您可能会发现被调用的命令会对参数的数量产生阻塞。

答案 2 :(得分:15)

来自男人

  

-exec命令;

          执行命令;如果返回0状态,则返回true。以下全部           查找的参数被用作命令的参数,直到           由';'组成的参数遇到了。字符串'{}'           被当前正在处理的文件名替换           它出现在命令的参数中,而不仅仅是在参数中           它在哪里,就像在某些版本的find中一样。这两个           构造可能需要转义(使用'\')或引用           保护它们免受外壳膨胀。参见实施例           有关使用'-exec'选项的示例。特定的           为每个匹配的文件运行一次fied命令。命令是           在起始目录中执行。有不可避免的           围绕使用-exec选项的安全问题;您           应该使用-execdir选项。   

-exec command {} +

          -exec选项的此变体运行指定的命令           选定的文件,但命令行是通过追加建立的           每个选定的文件名末尾; invoca-的总数           命令的tions将远远小于数量           匹配的文件。命令行的构建方式大致相同           xargs构建其命令行。只有一个'{}'实例           在命令中是允许的。该命令在执行中   该           起始目录。

所以我理解它的方式,\;执行单独的命令,+附加每个名称。它基本上就是它的执行方式,因为它是一个转义所以它的

ls testdir1; ls testdir2 

VS

ls testdir1 testdir2

在我的shell中执行上述操作会镜像输出您的问题。

更新2

那么,你为什么要使用+

说我有两个文件1.tmp和2.tmp

1.tmp

  

1
  2
  3

2.tmp

  

0
  2
  3个

正在运行

 find *.tmp -exec diff {} \;
> diff: missing operand after `1.tmp'
> diff: Try `diff --help' for more information.
> diff: missing operand after `2.tmp'
> diff: Try `diff --help' for more information.

如果您使用+并连接查找结果,请执行以下操作:

find *.tmp -exec diff {} \+
1c1,3
< 1
---
> 0
> 2
> 30

所以在这种情况下它的区别是diff 1.tmp; diff 2.tmp和diff 1.tmp 2.tmp

有些情况下\;是合适的+将是必要的。使用+ with rm就是这样一个实例,如果要删除大量文件,速度会大大提高;我总是喜欢学习更多关于find的知识,它是如此强大且方便的实用程序,我希望这足以解释这些差异。

答案 3 :(得分:9)

这是交易: find 具有特殊语法。您可以使用{},因为它们具有找到找到的文件的路径名的意义,并且(大多数)shell不会解释它们。你需要反斜杠\;,因为分号对shell有意义,它在 find 之前就可以得到它。那么 find 想要看到shell完成之后,在传递给C程序的参数列表中是

  

“ - exec”,“rm”,“{}”,“;”

但是你需要在命令行上使用\;来通过shell获得一个分号到参数。

您可以使用\{\},因为\{\}的shell引用解释只是{}。同样,您可以使用“{}”。

无法做的是使用

 -exec 'rm {} ;'

因为shell将其解释为一个参数,

  

“ - exec”,“rm {};”

和“rm {};”不是命令的名称。 (至少除非有人真的搞砸了。)

<强>更新

区别在于

$ ls file1
$ ls file2

$ ls file1 file2

+正在命令行上连接名称。

答案 4 :(得分:1)

;(分号)或+(加号)之间的区别在于参数如何传递到find -exec / -execdir参数中。例如:

  • 使用 ;将执行多个命令(对每个参数分别执行),

    示例:

    $ find /etc/rc* -exec echo Arg: {} ';'
    Arg: /etc/rc.common
    Arg: /etc/rc.common~previous
    Arg: /etc/rc.local
    Arg: /etc/rc.netboot
    
      

    find的所有后续参数都被视为该命令的参数。

         

    字符串{}将替换为正在处理的当前文件名。

  • 使用 +将执行最少的命令(因为参数组合在一起)。它与xargs命令的工作方式非常相似,因此它将尽可能多地使用每个命令的参数,以避免超出每行参数的最大限制。

    示例:

    $ find /etc/rc* -exec echo Arg: {} '+'
    Arg: /etc/rc.common /etc/rc.common~previous /etc/rc.local /etc/rc.netboot
    
      

    通过在末尾附加每个选定的文件名来构建命令行。

         

    命令中只允许{}的一个实例。

另见:

答案 5 :(得分:-5)

我们试图找到家务管理文件。

找到。 -exec echo {} \;命令一直跑到最后没有结果。

找到。 -exec echo {} \ +有结果,只花了几个小时。

希望这有帮助。

相关问题