2015-05-19 56 views
3

我有一個日誌來處理版大約結構是這樣的:打印最後一個「窗口」與SED

... 
... 
sentinel 
marker 
... 
marker 
... 
sentinel 
marker 
... 

我想及以下sentinel之間的一切,我想最後一個這樣的「窗口」。下面的工作確定:

sed -e "1{h;d} ; 2,109{H;d} ; 110{H;g} ; /sentinel/h ; \${g;q} ; N ; D" file.log 

這裏,110是這個日誌 S之間的空間的粗略(但幾行內一致)的估計,但我不得不重新計算這個估計其他日誌,這是煩人的。

我不知道是否有一個更優雅的方式與sed實現這一目標,即自動返回和之間sentinel的最後一個窗口(我也會接受,說明了爲什麼你不能做到這一點的答案在sed)。

謝謝。

P.S.我知道可以用任何語言做到這一點,但我想鍛鍊肌肉。

回答

2

這可能會爲你工作(GNU SED):和保持空間sentinel之間

sed '/marker/,/sentinel/{/marker/h;//!H};$!d;x' file 

藏匿線(覆蓋舊與新的),並在文件打印的結束無論是在左擁有空間。

編輯:

上述溶液迎合和sentinel雙。如果這類原因很可能是缺少然後使用:

sed '/marker/,/sentinel/H;$!d;x;s/.*\(marker.*sentinel\).*/\1/p;d' file 

這樣可以節省所有marker/sentinel對在保持空間和在文件末尾刪除所有,但最後一個完整的對。

+0

完美,在POSIX版本(又名非GNU sed)的情況下,用新行代替最後的';'(在'!d'後面)並在'}之前加上';'(或換行) – NeronLeVelu

+0

不幸的是,這沒有奏效。我已經嘗試了一些這樣的事情。會發生什麼是'/ marker /,/ sentinel /'還會匹配'marker'和文件末尾之間的所有內容,所以它總是檢索文件的最後部分,而不管這裏是否有'sentinel'。 –

+0

@JohnMoeller見編輯。 – potong

0

如果你知道有文件中沒有空行,你可以這樣做:

sed -e '/^marker$/i\ 
\ 
' -e '/^sentinel$/a\ 
\ 
' input | awk '/sentinel/{l=$0}END{print l}' RS= 

(不知道我會打電話給那優雅:基本上你要插入的記錄之間的空行,並讓awk的RS的辛勤工作。如果你不能保證沒有空行,前/後處理的數據,以確保:

sed 's/^/x/' input | sed -e '/^xmarker$/i\ 
\ 
' -e '/^sentinel$/a\ 
\ 
' | awk '/sentinel/{l=$0}END{print l}' RS= | sed 's/^x//' 

(當然,你可能會避免額外的通過包裹他們入現有的sed sed和awk,但這個想法是(我認爲)更清晰。)