当我使用时
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
它找到所有类型的文件。但是当我-exec
在最后添加:
find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt" -exec sh -c 'echo "$0"' {} \;
看来它只打印.txt
文件。我究竟做错了什么?
注意:使用 MINGW (Git Bash)
答案1
寻找 。 -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"
是缩写:
寻找 。'('\ '('-f型-A-名称“*.htm*”')'-o\ '('-名称“*.js*”')'-o \ '('-名称“*.txt”')' \ ')' -打印
也就是说,因为没有行动指定了谓词(仅状况),-print
为符合条件的文件隐式添加一个操作。
(顺便说一句,这将打印非常规.js
文件(-type f
仅适用于.htm
文件))。
尽管:
寻找 。 -名称“*.htm*”-o -名称“*.js*”-o -名称“*.txt”\ -exec sh -c 'echo "$0"' {} \;
是缩写:
寻找 。'('-f型-A-名称“*.htm*”')'-o\ '('-名称“*.js*”')'-o\ '('-名称“*.txt”-A-exec sh -c 'echo "$0"' {} \;')'
对于find
(就像许多语言一样),和(-a
;省略时隐含)优先于或者( -o
),并添加显式操作谓词(此处-exec
)会取消-print
上面看到的隐式操作。
在这里,您想要:
find . '(' -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ')' \
-type f \
-exec sh -c 'echo "$0"' {} \;
或者:
find . '(' -name "*.htm*" -o -name "*.js*" -o -name "*.txt" ')' \
-type f \
-exec sh -c '
for i do
echo "$i"
done' sh {} +
以避免sh
每个文件运行一个。
(-type f
比它可能意味着从索引节点检索信息更昂贵-name
,最好放在后尽管某些find
实现确实会在内部重新排序检查以进行优化)。
答案2
这是隐含的括号。添加明确的括号。\(
\)
find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -exec sh -c 'echo "$0"' {} \;
或使用 xargs (我喜欢 xargs,我发现它更容易,但显然不那么便携)。
find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -print0 | xargs -0 -n1 echo