根据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
从当前目录递归;对于目录下的文件,则执行sh
run printf
(目录后加正斜杠);对于其他一切,它运行find
的print
操作。是和-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包括目录等),从左边开始:
-type d
如果当前文件是目录,则计算结果为 true,否则为 false。-exec ...
如果前面的表达式为 true,则评估当前文件是否为目录;它的评估涉及以当前文件作为参数运行,如果以状态 0 退出,sh -c 'printf "%s/\n" "$0"'
则结果为 true ,否则为 false。sh
-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 的命令行很丑,但查询却很好!