有没有简单的方法来设置sed
中的模式范围匹配,让第二个模式查找文件中的最后一次出现?第一[notice]
模式后发现如何匹配`sed`中的一行和最后一次出现的范围之间的范围?
sed -r '1,/\[notice\]/d' /var/log/apache2/error.log
会吐出每一行。但是,如果我能够使它成为最后的[notice]
模式,那会更好。
有没有简单的方法来设置sed
中的模式范围匹配,让第二个模式查找文件中的最后一次出现?第一[notice]
模式后发现如何匹配`sed`中的一行和最后一次出现的范围之间的范围?
sed -r '1,/\[notice\]/d' /var/log/apache2/error.log
会吐出每一行。但是,如果我能够使它成为最后的[notice]
模式,那会更好。
是坏,这可能为你工作(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
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
读取文件一次,可能对大文件
awk '{a[NR]=$0; /notice/ && b=NR} END {for(c=b+1;c<=NR;c++) print a[c]}'
你可以用'tac'阅读反向线条,管道,然后将结果再次输入到“tac”。 – 2013-05-07 16:21:48
是sed必须的? – Kent 2013-05-07 16:29:17
@ChristofferHammarström'tac'对静态文件来说很好,但是如果我做了'tail -f -s 0.1 /var/log/apache2/error.log | sed -r'1,/ \ [notice \]/d''那我就不能用了。 – Jamie 2013-05-08 17:38:35