如何在“sed”中匹配一条线和最后一次出现的图案之间的范围?

如何在“sed”中匹配一条线和最后一次出现的图案之间的范围?,sed,gnu,Sed,Gnu,是否有一种简单的方法可以在sed中设置模式范围匹配,让第二个模式查找文件中最后一个出现的模式 sed-r'1,/\[notice\]/d'/var/log/apache2/error.log 将在找到第一个[注意]模式后吐出每一行。但是如果我能让它成为最后一个[注意]模式,那就更好了。sed是一个非常好的工具,可以在一行中进行简单替换,对于任何其他文本操作,只需使用awk: $ cat file line 1 [notice] line 2 [notice] line 3 $ awk 'NR

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

sed-r'1,/\[notice\]/d'/var/log/apache2/error.log

将在找到第一个
[注意]
模式后吐出每一行。但是如果我能让它成为最后一个
[注意]
模式,那就更好了。

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
上面使用了文件的两个过程,第一个过程用于查找最后一次出现的图案的行号,第二个过程用于打印所需的行

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

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

读取一次文件,可能对大型文件不利

awk'{a[NR]=$0;/notice/&b=NR}END{for(c=b+1;c这可能适合您(GNU-sed):

将图案及其后的行存储在保留空间中。在文件末尾打印这些行(图案的前几行被最后一行覆盖)

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


您可以使用
tac
反向读取行,将其传输到sed,然后将结果再次传输到
tac
。@ChristofferHammarström
tac
对于静态文件很好,但是如果我执行类似
tail-f-s0.1/var/log/apache2/error.log | sed-r'1,/\[注意]/d'
那我就不能用它了。@Kent不是专门针对这个问题的,但我使用的是一个节省磁盘的嵌入式系统,它的“一网打尽”脚本工具是
sed
:一般来说(对我来说)拥有良好的
sed
印章很方便。@Jamie:如果你这样做,你怎么知道发生了
[注意]
是最后一个吗?感谢您的回复;我应该提到,输入文件是流式传输的,因此多次传输具有挑战性。不是吗?这不是挑战性的,这是不可能的。如何识别流中模式的最后一次出现?通过缓冲自上次出现以来的数据:最终可能会将整个文件读取到内存中,但这是不可能的只需一次传球就可以完成。Potong的回答暗示,虽然我对我不太满意。您只是说它不是文件,而是一条流。您无法分辨最后一个在流中的时间,因为您在流中接收的下一行可能包含相同的。
sed '/\[notice\]/{h;d};x;/./!{x;d};x;H;$!d;x;s/[^\n]*\n//' file
sed ':a;$!{N;ba};s/.*\[notice\][^\n]*\n//' file