如何在`sed`中匹配一行与最后一次出现的模式之间的范围?

时间:2013-05-07 15:58:17

标签: sed gnu

是否有一种简单的方法可以在sed中设置模式范围匹配,以使第二种模式查找文件中的最后一次出现?

sed -r '1,/\[notice\]/d' /var/log/apache2/error.log
找到第一个[notice]模式后,

会吐出每一行。但是,如果我能做到最后是[notice]模式,那就更好了。

3 个答案:

答案 0 :(得分:2)

sed是单行中简单替换的优秀工具,对于任何其他文本操作只需使用awk:

$ cat file
line 1
[notice]
line 2
[notice]
line 3

$ awk 'NR==FNR{if (/\[notice\]/) tgt=NR; next} FNR>tgt' file file
line 3

上面使用了2次文件传递,第一次传递找到最后一次出现的模式的行号,第二次传递来打印你想要的行。

另一种方法是将整个文件作为单个记录读取,然后除去最后一个[通知](和周围的空格/换行符)之外的所有内容,例如,用GNU awk:

$ gawk -v RS='\0' -v ORS= '{sub(/.*\[notice\]\s*/,"")}1' file
line 3

答案 1 :(得分:0)

一次读取文件,对于大文件可能不好

awk '{a[NR]=$0; /notice/ && b=NR} END {for(c=b+1;c<=NR;c++) print a[c]}'

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed '/\[notice\]/{h;d};x;/./!{x;d};x;H;$!d;x;s/[^\n]*\n//' file

将图案和线条存储在保留空间中。在文件结束时打印出这些行(模式的以前的itterations由最后一个写过)。

另一种方法是将整个文件啜饮到内存中然后删除不需要的部分(贪婪是你的朋友:):

sed ':a;$!{N;ba};s/.*\[notice\][^\n]*\n//' file