find 和 -prune,以及 GNU 和 POSIX 解释

find 和 -prune,以及 GNU 和 POSIX 解释

我的 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,为什么我需要-oafter ?-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

-pruneEXPR如果为 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或之外的任何操作-print-print则对整个表达式为 true 的所有文件执行。

在 上0-name "0" -prune计算结果为 true,因此将其打印出来。

这条规则也解释了为什么find .会有这样的行为。

GNU 和 POSIX 的解释是等效的:

  • “真的; ” 匹配“初级应始终评估为真;”
  • “如果该文件是一个目录,请不要进入其中。”匹配“如果它是一个目录,它将导致 find 不会从当前路径名下降。”
  • “如果给出了 -deep,那么 -prune 没有效果。”匹配“如果指定了 -depth 主节点,则 -prune 主节点无效。”

(引用修订后的find文件)。

-prune后面不一定要跟-o,并且有几个例子可以说明这一点POSIX 文档find。这个技巧对于限制find当前目录的直接内容特别有用:

find . ! -name . -prune -print

相关内容