在n次匹配后可靠地停止bash查找

  • 本文关键字:bash 查找 bash find
  • 更新时间 :
  • 英文 :


我正试图找到一种可靠的方法来停止/杀死10场比赛后的查找操作。下面的代码是一个不太优雅的例子。

find . -type f -iname "*.txt" -exec myscript.sh {} ;

其中myscript.sh目前只输出文件名match

我已经尝试了一些建议在这里找到,例如管道到头部-n 10或管道到grep -m 10。但这些并不能可靠地阻止发现。

是否有可靠的方法?

我试过了,没有成功:

find . -type f -iname "*.txt" -exec myscript.sh {} ; | head -n 10
find . -type f -iname "*.txt" -exec myscript.sh {} ; | head -n 10 && tail -f /var/log/kern.log & read -t 10 ;kill $!
find . -type f -iname "*.txt" -exec myscript.sh {} ; | grep -m .

您无法阻止find命令在终止之前生成超过10个匹配。shell并行运行findhead,find可以很容易地在其输出缓冲区中排队输出10行以上,然后才被shell终止管道。

可以做的是重构管道,以防止出现任何症状。例如,

find . -type f -iname "*.txt" -print0 |
head -z -n 10 |
xargs -r0 myscript.sh

这依赖于几个GNU扩展(即,find-print0选项打印文件名以空结束,head的相应-z选项,xargs的相应-0选项),所以它是不可移植的,但应该在大多数Linux发行版以及其他地方工作,如果你安装了GNU版本的标准实用程序(可能称为gfind,ghead,gxargs等)。

null终止对鲁棒性很重要;如果你有包含换行符的文件名,head等人可以在中间截断文件名,当然,xargs不能知道一些换行符是文件名的一部分,而不是参数分隔符。即使您目前没有任何文件名包含换行符,您也要防止这种情况发生,因为任何解决方案都不是一次性的-稍后当您遇到包含换行符的文件名时,故障排除将是冗长而复杂的。也可参见https://mywiki.wooledge.org/BashFAQ/020

或者重构-exec:

find . -type f -iname "*.txt" -exec sh -c '
for arg in $(seq 10); do
myscript.sh "$1"
shift
done
exit 222' _ {} +

exit 222应该导致find在第一次-exec调用后失败而中止。-exec之后的+使find传递尽可能多的参数,类似于xargs。(如果文件名真的长,并且/或者您的系统的ARG_MAX真的很小,那么在第一次调用中可能接收不到10个文件,但我认为这种情况是病态的。)

使用parallel,这符合我的要求

find . -type f -iname "*.txt" | head -n 10 | parallel -j1 'myscript.sh {}  '

最新更新