有没有办法让 find 命令搜索字符串或模式的第一个匹配项或出现的位置每个内多个文件?我一直在使用通常的语法:
find dir -iname '*.ext' -exec command 'pattern' {} \;
(我也碰巧正在搜索 pdf,-exec pdfgrep
但假设这将是一般问题的特殊情况,可能会在之后或单独处理。)
-quit
请记住,这与使用 find 和或进行搜索生成第一个结果的常见问题不同head -n 1
。
答案1
只需使用-m
GNU 的选项即可grep
在(在示例中)一场匹配后停止读取文件。
find dir -iname '*.ext' -exec grep -m 1 'pattern' {} \;
答案2
您可以使用 awk 脚本来完成此操作:
find dir -iname '*.ext' -exec awk '/pattern/{print;exit}' {} \;
答案3
如果搜索命令在第一个匹配后无法停止,您可以过滤其结果并仅保留第一个输出行:command 'pattern' /path/to/file | head -n 1
。该命令在退出时会收到 SIGPIPE 信号head
,因此由于缓冲,它可能会继续寻找更多匹配项,但如果有很多匹配项,它会在文件末尾之前停止。
由于您需要运行 shell 命令(以设置管道),因此需要sh
从调用find
。注意引号:您需要一层引号用于外壳,另一层用于以 开头的外壳find
。您可以在内壳命令周围放置单引号,并使用 hack 在单引号中工作'\''
(结束单引号文字,\'
对于文字单引号,并同时开始一个新的单引号文字),这样您就不需要模式中任何不同的引用(除非模式包含'
您表示为 的a '\''
,在这种情况下您需要这样做'\'\\\'\''
)。
find dir -iname '*.ext' -exec sh -c 'command '\''pattern'\'' "$0" | head -n 1' {} \;
您可以将其放在外面并将其作为参数传递,而不必担心引用模式。
find dir -iname '*.ext' -exec sh -c 'command "$0" "$1" | head -n 1' 'pattern' {} \;
仅调用一个 shell 并循环遍历文件会稍微快一些。
find dir -iname '*.ext' -exec sh -c '
for f; do command "$0" "$f" | head -n 1; done
' 'pattern' {} +