我有很多文件需要搜索某些字符串。我用来grep -rl 'pattern' *
查找包含该模式的文件。但是,我只对文件计数感兴趣 - 如果字符串出现在超过 N 个文件中,我希望 grep 在命中第 N 个匹配后立即停止(因为搜索整个文件层次结构是很长的操作)。如果它返回一些有意义的退出代码,那就太好了,但如果这是不可能的,那么我可以毫无问题地通过管道传递它wc
。
如何告诉 grep 在匹配第 N 个文件后停止搜索其他文件?
答案1
您可以将grep
结果通过管道传输到head
.
请注意,为了确保在第 N 次匹配后停止,您需要使用来stdbuf
确保grep
不缓冲其输出:
stdbuf -oL grep -rl 'pattern' * | head -n10
一旦head
消耗了 10 行,它grep
就会终止并接收,因为在消失SIGPIPE
时它仍然输出一些东西到管道。head
这假设没有文件名包含换行符。
答案2
虽然这并不完全是您所要求的,但我认为这可能适合您的需求,考虑到使用文件的数量可能会使您的脚本时间根据文件的大小等而变化,并且看看您如何尝试限制处理器时间,你可以
timeout -k 1m grep -rl 'pattern' *
这不是计算处理了多少文件以保持脚本快速运行,而是在指定的时间段过去后实际上关闭命令。在我的代码示例中,它是 1 分钟,但可以通过将 1m 替换为正确的相应后缀,将其更改为秒 (s) 小时 (h) 甚至天 (d)。例如,让它运行一个小时......
timeout -k 1h grep -rl 'pattern' *
我希望这可以帮助别人!
答案3
不纯粹grep
,但具有bash
:
i=0
grep -rl 'pattern' * | while read l ; do
i=$(($i+1))
echo $l
if [ $i -ge N ] ; then
echo "at least N matches"
break
fi
done
如果匹配的文件数量远多于匹配阈值,速度会更快N
。