发现:为什么 -a 运算符不能与 -print 结合使用?

syn*_*ror 3 find

假设我们在当前目录中使用 find 与音频文件(例如 MP3)和(重要的!)还有非 mp3 文件(例如 JPEG)存在于当前目录或其下方的某处。
除此之外,我们在那里有一个目录,其中包含一些其他音频文件(在示例中称为exclude_me),通过从文件搜索中排除,它应该符合其名称:

find . \( -type d -name 'exclude_me' -prune \) -o \( -type f -a -iname '*.mp3' -a -print \)
Run Code Online (Sandbox Code Playgroud)

(虽然在这种情况下不是绝对必要的,-a但为了清楚起见,我特意设置了一些多余的括号,以及额外的运算符。)

由于显式-print选项(参见http://mywiki.wooledge.org/UsingFind),这确实会省略“exclude_me”目录中的任何内容,并且仅从当前目录递归列出 *.mp3 文件。有时(并非总是)该alias命令对于find单行代码可能已经足够了,但该命令将需要在行的参数。
录取通知书的“* .MP3”参数-iname是之前-print在这种情况下,似乎没有办法与解决的问题alias

但是为什么不通过简单地交换两个选项来假装在数学中呢?
像这样:

find . \( -type d -name 'exclude_me' -prune \) -o \( -type f -a -print -a -iname '*.mp3' \)
Run Code Online (Sandbox Code Playgroud)

请记住,我设置了一个前提条件,即在 . 目录或其子目录。它已被设置为更清楚地证明这在引擎盖下无法按预期工作。没有它们,事情只会看起来工作正常。尽管单行中有不同的规范,但它们出现将导致非 mp3 文件也被列出-iname '*.mp3'。那么为什么-a运算符不像数学中的那样工作,其中“A + B”与“B + A”相同?或者,在以下find方面:

\( -type f -a -print -a -iname '*.mp3' \)
Run Code Online (Sandbox Code Playgroud)

应该是一样的

\( -type f -a -iname '*.mp3' -a -print \)
Run Code Online (Sandbox Code Playgroud)

或不?

有没有办法获得所需的结果-iname在行尾有参数,而不是介于两者之间?(除了丑陋的hackish解决方案,如grep -v exclude_me之类的)

ctr*_*lor 6

and并且or在许多编程语言中不是可交换的,例如 C、C++、C?、shells、find 等等。

他们使用从左到右评估的懒惰,即它首先评估左侧的术语,然后仅在需要时评估右侧的术语。所以在false and b,b不被评估,因为答案总是错误的。但是在b and false,b被评估,因为它还没有看到第二项是假的。

当术语是纯函数即谓词(返回布尔值且不执行其他任何操作)时,这没有任何区别,但是当它执行某些操作(有副作用)时,这很重要。

-print做某事。它打印,因此很重要。

注意,任何允许副作用(例如 -print)的系统都必须定义评估顺序,从左到右可能是最简单的。