2013-05-07 54 views
0

有沒有簡單的方法來設置sed中的模式範圍匹配,讓第二個模式查找文件中的最後一次出現?第一[notice]模式後發現如何匹配`sed`中的一行和最後一次出現的範圍之間的範圍?

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

會吐出每一行。但是,如果我能夠使它成爲最後的[notice]模式,那會更好。

+0

你可以用'tac'閱讀反向線條,管道,然後將結果再次輸入到「tac」。 – 2013-05-07 16:21:48

+0

是sed必須的? – Kent 2013-05-07 16:29:17

+0

@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

回答

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 
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 
+0

感謝您的回覆;我應該提到輸入文件是流式傳輸,因此多次傳遞都具有挑戰性。沒有? – Jamie 2013-05-08 17:40:54

+0

這並不具有挑戰性,這是不可能的。如何識別流中某個模式的最後一次出現? – 2013-05-08 18:14:32

+0

通過緩衝自上次發生以來的數據:可能最終將整個文件讀入內存,但可以通過單次傳遞完成。波通的回答暗示,雖然我沒有爲我工作。 – Jamie 2013-05-13 16:10:43

0

讀取文件一次,可能對大文件

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