如何用sed删除最后一个匹配pattern行之前的2行文本?
解决方案
方法1:结合tac与sed实现
利用tac反转文件顺序,定位最后一个pattern(反转后变为第一个出现的pattern),只删除它之后的两行(对应原文件中它之前的两行),再反转回来即可:
tac file | sed '/pattern/{n;n;d;}' | tac > tmpfile && mv tmpfile file
命令解释:
tac file:将文件内容反转,此时原文件最后一行hhh变为第一行,最后一个pattern变为第一个出现的patternsed '/pattern/{n;n;d;}':匹配到pattern行后,读取下两行(n;n)并删除这两行(d),保留pattern行本身- 再次用
tac反转恢复原顺序,最后覆盖原文件
方法2:用awk精准定位(可读性更强)
通过awk存储所有行,找到最后一个pattern的行号后跳过其前两行输出:
awk ' { lines[NR] = $0 } END { for (i=NR; i>=1; i--) { if (lines[i] == "pattern") { last_pat = i break } } for (i=1; i<=NR; i++) { if (i != last_pat-1 && i != last_pat-2) { print lines[i] } } } ' file > tmpfile && mv tmpfile file
你之前命令的问题分析
sed -i '/pattern/{N;N;d;}' file:这个命令会匹配所有pattern行,然后删除当前行+后面两行,而你需要删除的是最后一个pattern前面的两行,方向完全相反,因此没有效果。tac file | sed '/pattern/,+2 d' | tac ...:/pattern/,+2 d会删除pattern行本身以及后面两行,这就是为什么你的pattern行被删掉了,不符合需求。
内容的提问来源于stack exchange,提问作者Ira
相关产品推荐
相关产品推荐

