我的 GNU findutils (FSF 2015) 说:
-prune
True;
if the file is a directory, do not descend into it.
If -depth is given, false; no effect.
Because -delete implies -depth, you cannot usefully use -prune and -delete together.
还有Posix:
-prune
The primary shall always evaluate as true;
it shall cause find not to descend the current pathname if it is a directory.
If the -depth primary is specified, the -prune primary shall have no effect.
我只改变了换行符。有两件事值得注意:
这不是完全忽略了-prune
主要作用吗?即“收集”左侧的表达式,并将其余的留给-o
右侧的 - 连接表达式?
通过 GNU 的手册页,您至少可以看到一个示例:
-name pattern
Base of ...
...
...
To ignore a directory and the files under it, use -prune;
see an example in the description of -path.
...
嗯,有一个简单的例子find . EXPR -prune -o -print
。这自然会产生一个问题:为什么find .
要打印任何东西。
回想起来,布置得很好,一切都在那里。
现在相关问题:
-prune
这两种解释(GNU 与 POSIX)有何关系?
在我看来,posix 似乎拿了一份枯燥的技术列表和一个有用的提示,然后无缘无故地将其变成了行话散文。这甚至具有误导性。
因为最终这两种解释都会让你问:
如果 after 总是返回 true,为什么我需要-o
after ?-prune
这是一个经过测试的示例:我有一些要跳过的挂载点,并且还想跳过 ramdisk“0”(零),并且想要列出包含“test”的所有文件,
find . -xdev -name "0" -prune -o -name '*test*'
像这样它就可以工作了;它还包括一行./0
,这实际上很有趣。
如果没有 prune-o-trick,即使使用显式的-print
.
答案1
这不是完全忽略了
-prune
主要作用吗?即“收集”左侧的表达式,并将其余的留给-o
右侧的 - 连接表达式?
不,他们并没有忽略它,因为这根本不是s 的效果,而是s 运算符优先级-prune
的结果。find
find . EXPR -prune -o -print
相当于
find . \( EXPR -prune \) -o -print
-prune
EXPR
如果为 true则进行评估。如果EXPR
为 false,-prune
则不求值,并且复合表达式的求值结果为 false;如果EXPR
为 true,则由于-prune
始终为 true,因此复合表达式的计算结果为 true。所有这一切的结果是,-print
仅在为 false 时才进行评估EXPR
,无论是什么-prune
。
find . -xdev -name "0" -prune -o -name '*test*'
由于以下规则(引用联机帮助页),打印./0
以及各种匹配:*test*
如果整个表达式不包含除
-prune
或之外的任何操作
在 上0
,-name "0" -prune
计算结果为 true,因此将其打印出来。
这条规则也解释了为什么find .
会有这样的行为。
GNU 和 POSIX 的解释是等效的:
- “真的; ” 匹配“初级应始终评估为真;”
- “如果该文件是一个目录,请不要进入其中。”匹配“如果它是一个目录,它将导致 find 不会从当前路径名下降。”
- “如果给出了 -deep,那么 -prune 没有效果。”匹配“如果指定了 -depth 主节点,则 -prune 主节点无效。”
(引用修订后的find
文件)。
-prune
后面不一定要跟-o
,并且有几个例子可以说明这一点POSIX 文档find
。这个技巧对于限制find
当前目录的直接内容特别有用:
find . ! -name . -prune -print