如何使用awk或sed提取两个标记模式间的最后匹配段落?
提取两个标记间最后一个匹配段落的方法
我来给你分享用awk和sed实现的两种方案,完美解决你要提取最后一段匹配内容的需求~
用awk实现
awk的思路是先缓存所有匹配的段落,最后只输出最后一个,代码如下:
awk '/abc/{flag=1; buf=""; next} /mno/{flag=0; last_buf=buf} flag{buf=buf $0 "\n"} END{print last_buf}' your_file
拆解下逻辑:
- 当遇到起始标记
abc时,开启匹配标记flag,清空临时缓冲区buf,跳过当前行(避免把abc本身存进去) - 当遇到结束标记
mno时,关闭flag,并把当前缓存的buf存到last_buf(更新为最新的匹配段落) - 只要
flag为1(处于匹配区间内),就把当前行内容追加到buf里 - 最后在
END块输出last_buf,就能得到最后一个匹配的段落啦
对应你的示例,执行后会输出:def2 ghi2 jkl2
用sed实现
sed有两种思路,推荐第二种更直观的:
方法一:利用保持空间累积内容
sed -n '/mno/{x;p;x}; /abc/{x;s/.*//;x}; H; ${x;s/.*abc\n//;s/\nmno.*//;p}' your_file
这个是通过sed的保持空间(hold space)来逐步累积内容,最后在文件末尾时,剔除掉abc之前和mno之后的内容,只保留中间的目标段落。
方法二:反转文件处理(更易懂)
先把文件内容反转,这样原来的最后一个匹配段落就变成第一个,提取后再反转回来:
tac your_file | sed -n '/mno/,/abc/{/mno/b;/abc/q;p}' | tac
拆解逻辑:
tac your_file:把文件内容行反转,原来的最后一行变第一行sed -n '/mno/,/abc/{/mno/b;/abc/q;p}':在反转后的内容里,找到第一个mno到abc的区间,跳过mno本身,遇到abc就停止,只打印中间的行- 最后再用
tac反转回来,就得到原文件中最后一个匹配的段落了
这个方法逻辑清晰,新手也容易理解,同样能输出你要的def2 ghi2 jkl2
内容的提问来源于stack exchange,提问作者GauravM
相关产品推荐
相关产品推荐

