为什么“find -o -print”没有输出?

为什么“find -o -print”没有输出?

我得到了一个我不理解的 unix‘find’命令的结果。

使用 MacOS 上的终端(我相信它是符合 POSIX 标准的操作系统)运行此 shell 脚本:

#!/bin/bash
#
echo "version 1" 
find . -iname "*tif" -o -iname "*foo"
#
echo "version 2" 
find . -iname "*tif" -o -iname "*foo" -print

我得到的结果:

version 1
./file1.tif
./file2.tif
./file3.tif
version 2
%

我希望获得相同的输出。 为什么使用“或”进行“打印”会抑制输出并导致找不到任何内容?

答案1

此命令:

find . -iname "*tif" -o -iname "*foo"

相当于:

find . \( -iname "*tif" -o -iname "*foo" \) -print

换句话说,隐式表达式-print不是无意识地添加到末尾的。它是在将显式表达式作为一个整体处理后添加到末尾的。这在POSIX 规范find

如果不存在表达式,-print则应使用作为表达式。否则,如果给定的表达式不包含任何原语-exec-ok-print,则给定的表达式应被有效地替换为:

( given_expression ) -print

在 shell 中,您需要转义或引用每个括号,因此在我上面的代码中\(是 和\)。还请注意,您的实现find可能会将某些内容(例如-printf)添加到抑制隐式 的初始项列表中-print

您的其他命令是:

find . -iname "*tif" -o -iname "*foo" -print

它相当于:

find . -iname "*tif" -o \( -iname "*foo" -a -print \)

括号的位置暗示了这样一个事实-a(即使你省略它),其约束力“比”更强-o

现在,手册的以下片段是相关的:

expression -o expression
主元交替;或运算符。如果第一个表达式为真,则不应计算第二个表达式。

在我们的例子中,第二个表达式是括号的全部内容。如果给定文件的-iname "*tif"求值结果为真,则-iname "*foo" -a -print根本不求值。

这种“完全”的后果有些令人惊讶,在以下命令中体现出来,其中出现了两次-iname "*tif"

find . -iname "*tif" -o -iname "*tif" -print

此命令永远不会-print。对于任何文件:

  • 要么第一个-iname "*tif"为真,则之后的所有内容-o都不会被评估;
  • 或者第一个-iname "*tif"为假,因此第二个-iname "*tif"被评估并且也是假,所以-print不被评估。

find . expression1 -o expression2 -print-print当且仅当expression1求值结果为假并且求值结果为真时,才会为路径名expression2

类似问题:将多个 find 命令合并为一个

相关内容