在find中使用分号(;)vs plus(+)和exec
为什么在使用之间的输出有差异
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
举一个例子可以很好地说明这一点。 比方说, find
这些文件:
file1 file2 file3
使用-exec
和分号( find . -exec ls '{}' \;
)将执行
ls file1 ls file2 ls file3
但是,如果使用加号( find . -exec ls '{}' \+
),尽可能多的文件名作为parameter passing给单个命令:
ls file1 file2 file3
文件名的数量只受系统最大命令行长度的限制。 如果该命令超过这个长度,该命令将被多次调用。
到目前为止所有的答案都是正确的。 我提供这个作为一个更清晰的(对我来说)使用echo
而不是ls
描述的行为的演示:
使用分号,命令echo
会在每个文件(或其他文件系统对象)中被调用一次:
$ find . -name 'test*' -exec echo {} \; ./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh
有了plus,命令echo
只被调用一次。 find的每个文件都作为参数传入。
$ find . -name 'test*' -exec echo {} \+ ./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh
如果find
大量的结果,你可能会发现命令被称为扼stream圈的参数的数量。
从男人
-exec命令;
执行命令; 如果返回0状态,则返回true。 以下所有的参数都被认为是命令的参数,直到由“;”组成的参数 遇到。 string“{}”被replace为当前文件名,在它发生在命令的参数中的任何地方都被处理,而不仅仅是在单独的参数中,就像在某些版本的find中一样。 这两个构造都可能需要被转义(用'\')或引号来保护它们免受shell的扩展。 有关使用“-exec”选项的示例,请参阅EXAMPLES部分。 指定的命令对每个匹配的文件运行一次。 该命令在起始目录中执行。 围绕使用-exec选项有一些不可避免的安全问题; 您应该使用-execdir选项。
-exec命令{} +
-exec选项的这种变体在所选文件上运行指定的命令,但是命令行是通过在最后附加每个选定的文件名来构build的; 该命令的总调用次数将远远less于匹配文件的数量。 命令行的构build方式与xargs构build其命令行的方式大致相同。 命令中只允许有一个“{}”实例。 该命令在起始目录中执行。
所以我理解它的方式, 执行单独的命令和+追加每个名字。 它基本上是被执行的方式,因为“逃脱”就是这样
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
所以在这种情况下它的差异1.tmp; diff 2.tmp和diff 1.tmp 2.tmp
有些情况下\; 是合适的,+将是必要的。 使用rm就是这样一个例子,如果你在删除大量文件的速度大大提高的话。 我总是喜欢学习更多关于发现,它是如此强大和方便的实用程序,我希望这足以解释的差异。
这是处理: find有特殊的语法。 你可以直接使用{}
,因为它们有意义地findfind的文件的path名,(大多数)shell不能解释它们。 你需要反斜杠\;
因为分号对shell有意义,在find之前就吃了。 那么,在传递给C程序的参数列表中, 发现想要在shell之后发现的东西是
“-exec”,“rm”,“{}”,“;”
但你需要\;
在命令行上通过shell获取分号给参数。
你可以用\{\}
因为\{\}
的shell引用解释就是{}
。 同样,您可以使用“{}”。
你不能做的是使用
-exec 'rm {} ;'
因为壳解释为一个参数,
“-exec”,“rm {};”
和“rm {}”; 不是一个命令的名字。 (至less除非有人真的搞砸了。)
更新
区别在于
$ ls file1 $ ls file2
和
$ ls file1 file2
+正在命令行上命名。
之间的区别;
(分号)或+
(加号)是如何将parameter passing到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
接下来的所有参数都被认为是命令的参数。
string
{}
被replace为正在处理的当前文件名称。 -
使用
+
会执行尽可能less的命令 (因为参数组合在一起)。 这与xargs
命令的工作原理非常相似,所以它将尽可能多地使用每个命令的参数,以避免超过每行参数的最大限制。例:
$ find /etc/rc* -exec echo Arg: {} '+' Arg: /etc/rc.common /etc/rc.common~previous /etc/rc.local /etc/rc.netboot
命令行是通过在最后附加每个选定的文件名来构build的。
在命令中只允许有一个
{}
实例。
也可以看看:
-
man find
- 在SO中使用分号(;)和加号(+)来执行find
- 简单的unix命令,什么是{}和\; 在SO
- find的-exec命令中的{} +是什么意思? 在Unix上
我们正在努力寻找pipe家的档案。
找 。 -exec echo {} \; 命令跑了一晚,最后没有结果。
找 。 -exec echo {} \ +有结果,只花了几个小时。
希望这可以帮助。