将表达式和操作与“find -o”一起使用

将表达式和操作与“find -o”一起使用

根据find的手册页,OR 与表达式一起使用:

expr1 -o expr2
              Or; expr2 is not evaluated if expr1 is true.

那么为什么它也适用于诸如-print本例中的 之类的操作呢?

find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print

(从使 find 在目录后显示斜杠?)。

答案1

行动是表达式也;它们是具有副作用的表达式。 (POSIX甚至没有提到行动。)

-exec的情况下,表达式的值反映了运行的命令的状态:如果成功(由退出代码 0 指示),则表达式的值为 true,否则为 false。所以

find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print

从当前目录递归;对于目录下的文件,则执行shrun printf(目录后加正斜杠);对于其他一切,它运行findprint操作。是和-or之间的析取;这里重要的值是s,而不是s。-type d -exec ...-print-type d-exec

更详细地说,find的优先规则意味着

find . -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; -or -print

可以更明确地写为

find . \( -type d -exec sh -c 'printf "%s/\n" "$0"' {} \; \) -or -print

连接表达式-or分别是

-type d -exec sh -c 'printf "%s/\n" "$0"' {} \;

-print

针对每个文件评估整个表达式集(在该术语的一般含义中,IE包括目录等),从左边开始:

  1. -type d如果当前文件是目录,则计算结果为 true,否则为 false。

  2. -exec ...如果前面的表达式为 true,则评估当前文件是否为目录;它的评估涉及以当前文件作为参数运行,如果以状态 0 退出,sh -c 'printf "%s/\n" "$0"'则结果为 true ,否则为 false。sh

  3. -print-type如果前一个表达式(和-exec)的结果是,则计算错误的,IE当前文件不是目录,或者是但sh失败。

答案2

一个小开关-o完全切换输出;有两个文件(包含“111”和“2 2”),以及两个与“test*”匹配的无法识别的目录

$ find .  -name 'test*'  \(  -exec cat {} \;   -print \) 2>/dev/null
1111 111 11111
./test
2 2 2 2
./test2


$ find .  -name 'test*'  \(  -exec cat {} \;  -o  -print \) 2>/dev/null
./testdir
./testdir2
1111 111 11111
2 2 2 2

第一个(隐式)在每次成功后-a执行。对于目录,错误消息被重定向,并且 -print 未“评估” - 逻辑 AND 链被破坏。-print-exec

第二个(“cat OR print”)仅在失败时打印。

prune 的例子隐藏在 man find 中;我很难理解它。

find . -path ./src/emacs -prune -o -print

这些 AND-OR-列表很棘手,而且优先级也很重要,然后您很快就需要这些漂亮的\(parens\). Find 的命令行很丑,但查询却很好!

相关内容