2014-10-03 27 views
1

我有了這樣的一個日誌文件:Unix的一個班輪匹配文件的2段

blah blah 
blah 
blah mypattern blah 
blah mypattern blah 
blah 
blah mypattern blah 
blah mypattern blah 
blah 

我想一個班輪閱讀上述從標準輸入(即單通過),用mypattern打印2組行,然後在打印第二組行後直接退出。

在情況下,我只想要一組線的我用下面的一行代碼:

sed '1,/mypattern/d' |sed '/mypattern/!q' 

,你可以看到,一條線在這裏還是沒有什麼大不了的。

編輯:這是我的粗略預計輸出

blah mypattern blah 
blah mypattern blah 
blah mypattern blah 
blah mypattern blah 

如果添加或在這裏或那裏錯過了線在邊界的兩邊,是不是一個大問題。重要的是,對於無限輸入,如果模式有2個有限部分,並且兩者之間有有限的間隙,則它將終止。

+0

什麼是你期望的輸出STED? – 2014-10-03 04:52:37

+0

您爲一組案例編寫的代碼不會打印該組的第一行。 – Barmar 2014-10-03 04:54:23

+0

@Barmar正確。我相信這一點,只要它能打印每一組的大部分內容 - 實際上比賽的起跑線和終點線並不重要。 – grasevski 2014-10-03 04:59:03

回答

2

這將統計與mypattern匹配的行組數,並在第二組結束後退出。因此,即使日誌文件是無限的,該命令也會終止。

awk '/mypattern/{c+=!f;f=1;print;next} {f=0} c==2{exit}' logfile 

說明:

的代碼有兩個變量:f是一個標誌和c是一個計數器。

  • /mypattern/{c+=!f;f=1;print;next}

    f是一個標誌。當我們位於匹配mypattern的一組行的外部時,以及當我們位於裏面時,它是零。

    對於任何與mypattern匹配的行,如果這是組中的第一行,即f==0,則組計數器c將遞增。然後將f設置爲1以表示我們現在在一個組中。該行被打印。 next命令告訴awk跳過任何剩餘的命令並重新開始下一行。

  • f=0

    如果我們得到這個說法,這意味着我們是一羣之外,因此該組標誌f設置爲零。

  • c==2{exit}

    如果我們得到這個說法,我們是一羣外,如果c==2,我們已經看到了兩個完整的團體。於是,我們exit awk。

+0

你'我贏得了代碼高爾夫。 ;-) – 5gon12eder 2014-10-03 05:28:38

1

技術上一個班輪,但只要你想也許不是那樣簡單。從正面來看,結果是確切的。

awk 'BEGIN { c=0; s=0; } /mypattern/ { if (!s) c++; s=1; print($0); next; } /./ { if (c >= 2) exit; s=0; }' 

它通過以下測試:

#!/bin/bash -eu 

function mkinput { 
    for i in $(seq $1) 
    do 
     hexdump /dev/urandom | head -n $((1 + $RANDOM % 10)) 
     for j in $(seq $((1 + $RANDOM % 10))) 
     do 
      echo "blah mypattern blah (i = $i, j = $j)" 
     done 
    done 
    # Produce an infinite stream of input. 
    hexdump /dev/urandom 
} 

mkinput 10 | awk 'BEGIN { c=0; s=0; } /mypattern/ { if (!s) c++; s=1; print($0); next; } /./ { if (c >= 2) exit; s=0; }' 

可能的輸出:

blah mypattern blah (i = 1, j = 1) 
blah mypattern blah (i = 1, j = 2) 
blah mypattern blah (i = 1, j = 3) 
blah mypattern blah (i = 2, j = 1) 
blah mypattern blah (i = 2, j = 2) 
0

這可能會爲你工作(GNU SED):

sed -n '/mypattern/{:a;p;n;//ba;x;s/^/x/;/xx/q;x}' file 

使用-n選項爲grep-like性質。在mypattern上進行過濾,並使用保留空間作爲計數器,以便何時退出處理。

或編程:

sed -n '/mypattern/{:a;p;n;//ba;H;x;s/\n/&/2;x;T;q}' file 
0

Perl中,相當長的內膽, 未經測試

perl -ne 'if (m/mypattern/) { $cnt++ unless $in; $in=1; print; } else { $in=0; exit if $cnt == 2; }' 

擴大, 「適當的Perl」 版本爲更好地理解:

my $cnt=0; 
my $in=0; 
while (<>) { 
    if m/mypattern/ { 
     $cnt++ unless $in; 
     $in = 1; 
     print; 
    } else { 
     $in = 0; 
     exit if $cnt == 2; 
    } 
} 

更新: Te與

aa 
aa mypattern aa 1 
aa mypattern aa 1 
aa mypattern aa 1 
aa 
aa 
aa mypattern aa 2 
aa 
aa mypattern aa 3 
aa mypattern aa 3 
aa mypattern aa 3 
aa 

返回

aa mypattern aa 1 
aa mypattern aa 1 
aa mypattern aa 1 
aa mypattern aa 2