Perl结合grep做多行匹配时如何输出匹配结果对应的文件名?
解决方案
你可以直接用Perl单行程式完成续行拼接、匹配、文件名输出全流程,不需要额外调用grep,也不用写shell循环:
方案1:纯Perl实现(性能最优)
perl -ne 'chomp; # 处理续行 if (/\\$/) { s/\\$//; $buf .= $_ . " "; next; } # 拼接完整行后匹配 $full_line = $buf . $_; $buf = ""; if ($full_line =~ /-field.*X.*-field.*Y/) { # 输出文件名 + 匹配内容 print "$ARGV: $full_line\n"; } ' a/b/c/*/records/*.rec
逻辑说明
- Perl内置变量
$ARGV自动存储当前正在读取的文件名,不需要额外处理 - 先把所有以
\结尾的续行拼入缓冲区,遇到非续行时再合并为完整行做匹配 - 匹配成功时同时输出文件名和匹配到的完整行内容
方案2:保留grep调用的实现
如果你习惯使用grep的参数(比如高亮匹配、输出上下文等),可以用以下命令:
find a/b/c/*/records -name "*.rec" -print0 | xargs -0 -I {} sh -c 'perl -pe "s/\\\n/ /" "{}" | grep -H --label="{}" "-field.*X.*-field.*Y"'
逻辑说明
- 用find逐文件传递给xargs处理,每个文件单独做续行拼接
--label参数给grep指定当前处理的文件名,-H强制输出文件名
注意事项
- 如果需要避免正则贪婪匹配跨多条记录命中,可把匹配规则里的
.*替换为非贪婪匹配.*?,即/-field.*?X.*?-field.*?Y/ - 纯Perl方案不需要为每个文件创建新进程,处理大量文件时性能远高于方案2
内容的提问来源于stack exchange,提问作者TKH
相关产品推荐
相关产品推荐

