有没有一种惯用的方法来检测“查找”是否找到任何匹配项?我目前正在使用
COUNT=`find ... | wc -l`
if [ "$COUNT" -gt 0 ]; then
但这对我来说似乎有点间接。另外,我希望 find 一旦找到匹配项就停止搜索,这样就不会浪费时间和精力。我只需要知道是否有匹配的文件。
更新:我犯了一个错误,就是在没有面前代码的情况下编写问题:我wc -l
在不同的情况下使用,无论如何我都需要知道找到的文件的总数。在我只测试是否有匹配的情况下,我使用的是if [ -z $(find …) ]
.
答案1
如果你知道你有 GNU find,请使用-quit
使其在第一场比赛后停止。
可移植地将 的输出通过管道传输find
到head -n 1
.这种方式find
会在几次匹配后(当它填满head
输入缓冲区时)因管道损坏而死亡。
无论哪种方式,您都不需要wc
测试字符串是否为空,shell 可以自行完成。
if [ -n "$(find … | head -n 1)" ]; then …
答案2
您可以使用-quit
第一场比赛后停止的动作。您可能希望将其与另一个操作(例如-print
)结合起来,否则您将无法判断它是否找到了任何东西。
例如,find ... -print -quit
将打印第一个匹配文件的路径,然后退出。或者,-printf 1 -quit
如果有匹配,您可以打印 1,如果不匹配,则不打印任何内容。
find
的退出状态反映了搜索时是否出现错误,而不是是否找到任何内容,因此您必须检查其输出以查看是否有匹配项。
答案3
Exit 0 对于 find 来说很容易,exit >0 则更难,因为这通常只会在出现错误时发生。然而我们可以让它发生:
if find -type f -exec false {} +
then
echo 'nothing found'
else
echo 'something found'
fi
请注意,此解决方案比使用子 shell 的性能更高;执行 false 肯定比执行 Dash 更快:
$ cat alfa.sh bravo.sh charlie.sh delta.sh
find -name non-existing-file -exec false {} +
find -name existing-file -exec false {} +
[ "$(find -name non-existing-file)" ]
[ "$(find -name existing-file)" ]
$ strace dash alfa.sh | wc -l
807
$ strace dash bravo.sh | wc -l
1141
$ strace dash charlie.sh | wc -l
1184
$ strace dash delta.sh | wc -l
1194
答案4
您可以将其包装到 shell 条件中,例如:
[ "$(find . ...)" '!=' '' ] && echo Found || echo Not found
...
你的匹配条件在哪里,例如-name *.txt
.
其他一些例子:
[ "$(find /etc -name hosts)" ] && echo True || echo False
[ ! -z "$(find /etc -name hosts)" ] && echo True || echo False