2012-03-26 32 views
0

我有一個日誌格式如下使用sed匹配多個線條圖案

<< 
[ABC] some other data 
some other data 
>> 

<< 
DEF some other data 
some other data 
>> 

<< 
[ABC] some other data 
some other data 
>> 

我想要的選擇,它們是具有ABC預期的結果的所有日誌是

<< 
[ABC] some other data 
some other data 
>> 

<< 
[ABC] some other data 
some other data 
>> 

什麼會爲sed命令的表達? 對於獲取內容的B/W < < >>表達將

sed -e '/<</,/>>/!d' 

但我怎麼能強迫它有[ABC]中的B/W

回答

1

這工作在我身邊:

awk '$0~/ABC/{print "<<";print;getline;print;getline;print }' temp.txt 

測試如下:

pearl.242> cat temp.txt 
<< 
[ABC] some other data 
some other data 
>> 
<< 
DEF some other data 
some other data 
>> 

nkeem 

<< 
[ABC] some other data 
some other data 
>> 
pearl.243> awk '$0~/ABC/{print "<<";print;getline;print;getline;print }' temp.txt 
<< 
[ABC] some other data 
some other data 
>> 
<< 
[ABC] some other data 
some other data 
>> 
pearl.244> 

如果DONOT想硬編碼此聲明print "<<";,那麼你可以去下面:

pearl.249> awk '$0~/ABC/{print x;print;getline;print;getline;print}{x=$0}' temp.txt 
<< 
[ABC] some other data 
some other data 
>> 
<< 
[ABC] some other data 
some other data 
>> 
pearl.250> 
0

對我來說,戰略經濟對話基礎線。你可以說它是多線的,但用awk或perl開始這個工作比在sed中嘗試做起來更容易。

我會用Perl和作出一點點的狀態機這樣的僞代碼(我不保證它會趕上你想什麼來實現每一個小細節)

state = 0; 
for each line 
    if state == 0 
     if line == '<<' 
      state = 1; 
    if state == 1 
     If line starts with [ABC] 
      buffer += line 
      state =2 
    if state == 2 
     if line == >> 
      do something with buffer 
      state = 0 
     else 
      buffer += line; 

參見http://www.catonmat.net/blog/awk-one-liners-explained-part-three/關於如何你可以使用awk爲1個襯墊做一些線索......

2

這可能會爲你工作:

sed '/^<</,/^>>/{/^<</{h;d};H;/^>>/{x;/^<<\n\[ABC\]/p}};d' file 
<< 
[ABC] some other data 
some other data 
>> 
<< 
[ABC] some other data 
some other data 
>> 

的sed配備了一個寄存器稱爲hold space(HS)。

您可以使用HS來收集感興趣的數據。在/^<</,/^>>/

h替換掉在HS與什麼是在圖案空間(PS)

H追加一個新行\n,然後將PS到HS

x交換之間這種情況下線路HS爲PS

NB這將刪除<<...>>之間包含[ABC]之間的所有行。 如果您想保留其他線路使用:

sed '/^<</,/^>>/{/^<</{h;d};H;/^>>/{x;/^<<\n\[ABC\]/p};d}' file 
<< 
[ABC] some other data 
some other data 
>> 


<< 
[ABC] some other data 
some other data 
>> 
+0

第二個表達式帶來了一切。 – 2012-03-26 10:49:02

+0

不,它會在符合'/^<< \ n \ [ABC \]/p'的範圍內打印那些行,以及完全在範圍外的任何行。在這種情況下,「/^<> /' – potong 2012-03-26 11:38:18

+0

N.B. '/^<< \ n \ [ABC \]/p'可以縮寫爲'/ ABC/p' – potong 2012-03-26 11:45:01

0

TXR:專爲多線路設計。

@(collect) 
<< 
[ABC] @line1 
@line2 
>> 
@ (output) 
>> 
[ABC] @line1 
@line2 
<< 

@ (end) 
@(end) 

運行:

$ txr data.txr data 
>> 
[ABC] some other data 
some other data 
<< 

>> 
[ABC] some other data 
some other data 
<< 

非常基本的東西;你可能會更好地堅持awk,直到你有一個非常複雜的多行提取作業,數據不規則,數量衆多的情況下,大量的嵌套等。

如果日誌非常大,我們應該寫@(collect :vars())所以收集不會隱含地累積列表;那麼作業將運行在不斷的內存中。

此外,如果日誌不總是兩行,它會變得更復雜一點。我們可以使用嵌套收集來收集可變數量的行。

@(collect :vars()) 
<< 
[ABC] @line1 
@ (collect) 
@line 
@ (until) 
>> 
@ (end) 
@ (output) 
>> 
[ABC] @line1 
@ {line "\n"} 
<< 

@ (end) 
@(end)