0

有没有一种简单的方法来设置模式范围匹配,sed让第二个模式查找文件中的最后一次出现?

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

[notice]将在找到第一个模式后吐出每一行。[notice]但如果我能把它变成最后一个模式,那就更好了。

4

3 回答 3

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 遍,第一遍查找模式最后一次出现的行号,第二遍打印所需的行。

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

$ gawk -v RS='\0' -v ORS= '{sub(/.*\[notice\]\s*/,"")}1' file
line 3
于 2013-05-07T18:20:12.990 回答
0

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

awk '{a[NR]=$0; /notice/ && b=NR} END {for(c=b+1;c<=NR;c++) print a[c]}'
于 2013-05-07T19:58:09.337 回答
0

这可能对您有用(GNU sed):

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

将图案和之后的线条存储在保持空间中。在文件末尾打印出这些行(模式的前迭代被最后一个覆盖)。

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

sed ':a;$!{N;ba};s/.*\[notice\][^\n]*\n//' file
于 2013-05-08T04:49:29.983 回答