为什么使用之间的输出存在差异
find . -exec ls '{}' \+
Run Code Online (Sandbox Code Playgroud)
和
find . -exec ls '{}' \;
Run Code Online (Sandbox Code Playgroud)
我有:
$ find . -exec ls \{\} \+
./file1 ./file2
.:
file1 file2 testdir1
./testdir1:
testdir2
./testdir1/testdir2:
$ find . -exec ls \{\} \;
file1 file2 testdir1
testdir2
./file2
./file1
Run Code Online (Sandbox Code Playgroud)
Mar*_*tin 222
用一个例子可能最好地说明了这一点.让我们说find
这些文件:
file1
file2
file3
Run Code Online (Sandbox Code Playgroud)
使用-exec
分号(find . -exec ls '{}' \;
),将执行
ls file1
ls file2
ls file3
Run Code Online (Sandbox Code Playgroud)
但是如果你使用加号代替(find . -exec ls '{}' \+
),尽可能多的文件名作为参数传递给单个命令:
ls file1 file2 file3
Run Code Online (Sandbox Code Playgroud)
文件名的数量仅受系统的最大命令行长度限制.如果命令超过此长度,则将多次调用该命令.
Joh*_*web 35
到目前为止,所有答案都是正确的.我提供这个更清楚(对我来说)使用echo
而不是ls
:
使用分号,echo
每个文件(或其他文件系统对象)找到一次命令:
$ find . -name 'test*' -exec echo {} \;
./test.c
./test.cpp
./test.new
./test.php
./test.py
./test.sh
Run Code Online (Sandbox Code Playgroud)
使用加号,该命令echo
仅被调用一次.找到的每个文件都作为参数传入.
$ find . -name 'test*' -exec echo {} \+
./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh
Run Code Online (Sandbox Code Playgroud)
如果find
出现大量结果,您可能会发现被调用的命令会对参数的数量产生阻塞.
mat*_*hew 16
来自那个男人
-exec命令;
执行命令; 如果返回0状态,则返回true.查找的所有后续参数都被视为命令的参数,直到由';'组成的参数为止 遇到了.字符串"{}"将被当前文件名替换,该文件名将在命令的参数中出现,而不仅仅是在单独的参数中,就像在某些版本的find中一样.这两种结构都可能需要进行转义(使用'\')或引用以保护它们不被shell扩展.有关使用'-exec'选项的示例,请参见示例部分.为每个匹配的文件运行一次指定的命令.该命令在起始目录中执行.使用-exec选项时存在不可避免的安全问题; 你应该使用-execdir选项.
-exec命令{} +-exec选项的此变体在所选文件上运行指定的命令,但命令行是通过在末尾附加每个选定的文件名来构建的; 命令的调用总数将远远少于匹配文件的数量.命令行的构建方式与xargs构建命令行的方式大致相同.命令中只允许一个"{}"实例.该命令在起始目录中执行.
所以我理解它的方式,\; 执行单独的命令,+附加每个名称.它基本上就是它的执行方式,因为它是一个逃避所以它
ls testdir1; ls testdir2
Run Code Online (Sandbox Code Playgroud)
VS
ls testdir1 testdir2
Run Code Online (Sandbox Code Playgroud)
在我的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.
Run Code Online (Sandbox Code Playgroud)
如果您使用+并连接查找结果,如下所示:
find *.tmp -exec diff {} \+
1c1,3
< 1
---
> 0
> 2
> 30
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下它的区别是差异1.tmp; diff 2.tmp和diff 1.tmp 2.tmp
有些情况下\; 是合适的+将是必要的.使用+ with rm就是这样一个实例,如果要删除大量文件,速度会大大提高; 我总是喜欢学习更多关于find的知识,它是如此强大且方便的工具我希望这足以解释差异.
这是交易:find有特殊的语法.您可以使用{}
原样,因为它们具有找到找到的文件的路径名的意义,并且(大多数)shell不会解释它们.你需要反斜杠,\;
因为分号对shell有意义,它会在找到之前把它吃掉.因此,在传递给C程序的参数列表中,找到想要在shell完成之后看到的是
"-exec","rm","{}",";"
但是你需要\;
在命令行上通过shell获得一个分号到参数.
你可以逃脱,\{\}
因为shell引用的解释\{\}
只是{}
.同样,您可以使用"{}".
你不能做的是使用
-exec 'rm {} ;'
Run Code Online (Sandbox Code Playgroud)
因为shell将其解释为一个参数,
"-exec","rm {};"
和"rm {};" 不是命令的名称.(至少除非有人真的搞砸了.)
更新
区别在于
$ ls file1
$ ls file2
Run Code Online (Sandbox Code Playgroud)
和
$ ls file1 file2
Run Code Online (Sandbox Code Playgroud)
+正在命令行上连接名称.
;
(分号)或(加号)之间的区别+
在于参数如何传递到 find 的-exec
/-execdir
参数中。例如:
using;
将执行多个命令(每个参数分别执行),
例子:
$ find /etc/rc* -exec echo Arg: {} ';'
Arg: /etc/rc.common
Arg: /etc/rc.common~previous
Arg: /etc/rc.local
Arg: /etc/rc.netboot
Run Code Online (Sandbox Code Playgroud)
以下所有参数都
find
被视为该命令的参数。该字符串
{}
将替换为当前正在处理的文件名。
using+
将执行最少可能的命令(因为参数组合在一起)。它与xargs
命令的工作方式非常相似,因此它将在每个命令中使用尽可能多的参数,以避免超出每行参数的最大限制。
例子:
$ find /etc/rc* -exec echo Arg: {} '+'
Arg: /etc/rc.common /etc/rc.common~previous /etc/rc.local /etc/rc.netboot
Run Code Online (Sandbox Code Playgroud)
命令行是通过在末尾附加每个选定的文件名来构建的。
{}
命令中只允许出现一个 的实例。
也可以看看:
man find