在Linux命令中“ {} \;”是什么意思?


37

有时我看到以下命令:

find . -name  * -exec ls -a {} \;

我被要求执行此操作。

{} \;是什么意思?


1
-name *是多余的。
凯文

3
另外,请查看explainshell了解其他此类问题。这是您的命令的输出。
谷氨酰胺

8
-name *比冗余更糟糕。由于*未引用,因此Shell会将其扩展到当前文件夹中的文件名列表,其中空格会被错误地处理,从而导致意外结果或错误消息。另外,它find具有许多功能,其中之一是列出文件。这避免了必须使用-exec。例如,您可以使用find . -printfind . -ls。最后,有两种方法可以逃脱分号:就像使用反斜杠一样\;,或者引用:';'。使用任何您觉得更舒适的方式。
Paddy Landau

Answers:


48

如果运行findexec{}扩展到每个文件或目录中的文件名find(以便ls在您的示例获取每个FOUND文件名作为参数-请注意,它调用ls或您指定的任何其他命令一次为每个文件中找到)。

分号;结束由执行的命令exec。它需要使用进行转义,\以便您在其中运行的shell find不会将其视为自己的特殊字符,而会将其传递给find

有关更多详细信息,请参见本文


此外,find还提供了一些优化功能exec cmd {} +-像这样运行时,find将找到的文件追加到命令末尾,而不是每个文件调用一次(因此,如果可能,该命令仅运行一次)。

如果使用,则行为上的差异(如果不是效率上的差异)很容易注意到ls,例如

find ~ -iname '*.jpg' -exec ls {} \;
# vs
find ~ -iname '*.jpg' -exec ls {} +

假设您有一些jpg文件(具有足够短的路径),则结果在第一种情况下每个文件一行ls,而在后者的列中显示文件的标准行为。


1
我认为\;与您进行对比将是有益的+
凯文

find . -name * | ls -a -有何不同?
安德拉斯悍马

@DrH的要点不是让shell进行通配符扩展,而是将通配符表达式传递给find。另外,ls在这种情况下,输出显然不依赖于输入-不管我用作的过滤器findls仅显示工作目录的内容,仅此而已。检查例如find ~ -iname '*.jpg' -exec ls -a {} \;VS find ~ -iname '*.jpg' | ls -a
moon.musick

@DrH甚至echo 'foo' | ls -a
moon.musick

@ moon.musick,我相信你已经错过了关重要的-ls -a -测试时是什么// @博士小时查询命令。
Daniel Llewellyn

20

find命令联机帮助页图标的手册页中

-exec command ;
              Execute  command;  true if 0 status is returned.  All following arguments to find are taken to be arguments to
              the command until an argument consisting of `;' is encountered.  The string `{}' is replaced  by  the  current
              file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it
              is alone, as in some versions of find.  Both of these constructions might need to be escaped (with a  `\')  or
              quoted  to  protect them from expansion by the shell.

所以这是解释:

{}表示“的输出find”。如“什么都find找到”。find返回您要查找的文件的路径,对吗?因此{}替换它;它是find命令定位的每个文件的占位符(从此处获取)。

\;部分基本上是在告诉find“好,我已经完成了要执行的命令”。

例:

假设我位于一个充满.txt文件的目录中。然后,我运行:

find . -name  '*.txt' -exec cat {} \;

第一部分,find . -name *.txt返回.txt文件列表。第二部分,-exec cat {} \;将对,so ,等等cat找到的每个文件执行命令。findcat file1.txtcat file2.txt


4
该零件*.txt必须引用为'*.txt'。这是因为如果.txt当前文件夹中有文件,则外壳程序将对此文件进行扩展,并且您将得到不正确的结果或错误消息。find -name '*.txt' -exec cat {} \;
帕迪·兰道

@Alaa Ali很好地解释了
pushya
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.