为什么使用
之间的输出存在差异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
答案 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 {} \ +有结果,只花了几个小时。希望这有帮助。