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

-1 find

我的 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.
Run Code Online (Sandbox Code Playgroud)

和 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.
Run Code Online (Sandbox Code Playgroud)

我只改变了换行符。有两点值得注意:

是不是都完全忽略了-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.
    ...
Run Code Online (Sandbox Code Playgroud)

嗯,有一个简单的例子find . EXPR -prune -o -print。这会自动提出为什么要find .打印任何东西的问题。

回想起来,布置得很好,一切都在那里。

现在相关的Q:

这两种-prune解释(GNU vs. POSIX)有什么关系?

对我来说,posix 似乎把一个枯燥的技术列表和一个有用的提示变成了行话散文。它甚至具有误导性。

因为最后这两种解释都会让你问:

为什么我需要-oafter -prune,如果它总是返回真?

这是一个经过测试的示例:我有一些挂载点要跳过,也想跳过 ramdisk“0”(零),并想列出所有包含“test”的文件,

find . -xdev -name "0" -prune -o -name '*test*'

像这样它工作; 它还包括一行./0,这实际上很有趣。

没有 prune-o-trick,即使使用显式-print.

Ste*_*itt 5

是不是都完全忽略了-prune主效应?即“收集”左侧的表达式,并将其余的留给-o右侧的- 连接表达式?

不,他们没有忽略它,因为这根本不是-prune的效果,而是find运算符优先级的结果。

find . EXPR -prune -o -print
Run Code Online (Sandbox Code Playgroud)

相当于

find . \( EXPR -prune \) -o -print
Run Code Online (Sandbox Code Playgroud)

-prune如果EXPR为真则进行评估。如果EXPR为假,-prune则不求值,复合表达式求值为假;如果EXPR为真,因为-prune始终为真,复合表达式的计算结果为真。所有这一切的结果是,-print仅在EXPR为假时才进行评估,而不管结果如何-prune

find . -xdev -name "0" -prune -o -name '*test*'
Run Code Online (Sandbox Code Playgroud)

由于以下规则(引用联机帮助页),打印./0以及各种*test*匹配项:

如果整个表达式不包含除-prune或之外的任何操作-print-print则对整个表达式为真的所有文件执行。

On 0-name "0" -prune计算结果为真,所以它被打印出来。

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

GNU 和 POSIX 的解释是等价的:

  • “真的; ”匹配“主要应始终评估为真;”
  • “如果文件是一个目录,就不要进入它。” 匹配“如果它是一个目录,它将导致 find 不下降当前路径名。”
  • “如果给定了 -depth,则 -prune 无效。” 匹配“如果指定了 -depth 主,则 -prune 主将无效。”

(引用修改后的find文档)。

-prune后面不必跟-o,并且在POSIX 文档find中有一些示例说明了这一点。这个技巧对于限制find当前目录的直接内容特别有用:

find . ! -name . -prune -print
Run Code Online (Sandbox Code Playgroud)