如何检测“find”是否找到任何匹配项?

如何检测“find”是否找到任何匹配项?

有没有一种惯用的方法来检测“查找”是否找到任何匹配项?我目前正在使用

COUNT=`find ... | wc -l`
if [ "$COUNT" -gt 0 ]; then

但这对我来说似乎有点间接。另外,我希望 find 一旦找到匹配项就停止搜索,这样就不会浪费时间和精力。我只需要知道是否有匹配的文件。

更新:我犯了一个错误,就是在没有面前代码的情况下编写问题:我wc -l在不同的情况下使用,无论如何我都需要知道找到的文件的总数。在我只测试是否有匹配的情况下,我使用的是if [ -z $(find …) ].

答案1

如果你知道你有 GNU find,请使用-quit 使其在第一场比赛后停止。

可移植地将 的输出通过管道传输findhead -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

相关内容