补充olivm's helpful answer 并解决OP 对需要-o 的困惑:
-
-prune,就像每个 find 主要(用 GNU 说的动作或测试)一样,返回一个 Boolean,并且在-prune。
- 如果没有显式的运算符,主元素与
-a (-and) 隐式连接,这与它的兄弟 -o (-or) 一样执行短路布尔逻辑。李>
-
-a 的优先级高于 -o。
有关所有find 概念的摘要,请参阅https://stackoverflow.com/a/29592349/45375
因此,接受的答案,
find . -path ./ignored_directory -prune -o -name fileName.txt -print
等价于(括号用于明确计算优先级):
find . \( -path ./ignored_directory -a -prune \) \
-o \
\( -name fileName.txt -a -print \)
由于短路,评估如下:
- 匹配
./ignored_directory 的输入路径导致-prune 被评估;因为-prune 总是返回true,所以短路会阻止-o 运算符的右侧 侧被评估;实际上,什么都没有发生(输入路径被忽略)
- 输入路径与
./ignored_directory 不匹配,立即 - 再次由于短路 - 在-o 的右侧 侧继续评估:
- 仅当输入路径的文件名部分与
fileName.txt 匹配时,才会评估-print 主;实际上,仅打印文件名与 fileName.txt 匹配的输入路径。
编辑:尽管我最初在这里声明,-print 需要在 -o 的右侧;没有它,implied -print 将适用于 整个 表达式,因此 也 打印 left-hand边赛;有关背景信息,请参见下文。
相比之下,让我们考虑一下不使用-o 会发生什么错误:
find . -path ./ignored_directory -prune -name fileName.txt -print
这相当于:
find . -path ./ignored_directory -a -prune -a -name fileName.txt -a -print
这将仅打印修剪路径(也匹配-name过滤器),因为-name和-print原色(隐式)与逻辑与;
在这种特定情况下,由于./ignored_directory 不能同时匹配fileName.txt,所以会打印nothing,但如果-path 的参数是一个glob,它 有可能得到输出。
关于find隐式使用-print:
POSIX mandates 如果find 命令的表达式作为一个整体不包含任何一个
-
产生输出原色,例如
-print本身
-
执行某些东西的主要元素,例如
-exec 和-ok
- (给出的示例初选对于
find 的POSIX 规范而言是详尽无遗的,但是诸如GNU find 和BSD find 之类的实际实现添加了其他内容,例如输出-生产-print0primary,执行-execdirprimary)
-print 被应用隐式,就好像表达式被指定为:
\( expression \) -print
这很方便,因为它允许你写find .等命令,而不需要附加-print。
但是,在某些情况下需要明确的-print,如下所示:
假设我们没有在接受的答案末尾指定-print:
find . -path ./ignored_directory -prune -o -name fileName.txt
由于表达式中现在没有产生输出或执行的主节点,因此它被评估为:
find . \( -path ./ignored_directory -prune -o -name fileName.txt \) -print
这不会按预期工作,因为如果 整个 括号表达式的计算结果为真,它将打印路径,在这种情况下错误地包括修剪的目录。
相比之下,通过将-print 显式附加到-o 分支,仅当-o 表达式的右侧计算结果为true 时才会打印路径;使用括号使逻辑更清晰:
find . -path ./ignored_directory -prune -o \( -name fileName.txt -print \)
相比之下,如果左侧为真,则仅执行 -prune,这不会产生任何输出(并且由于 overall 表达式包含 -print,-print 是未隐式应用)。