2015-07-02 43 views
2

我有一個這樣的輸入文件:我怎麼算多個重疊的串並獲得每行的總出現次數(AWK或者別的什麼)

315secondbin x12121321211332123x 
315firstbin 3212212121x 
315thirdbin 132221312 
316firstbin 121 
316secondbin 1212 

我想做的是統計的多少實例幾行不同的字符串(比如說「121」和「212」)存在於每行計數重疊中。所以,我的預期產出將是:

6 
5 
0 
1 
2 

所以我稍微修改從另一個線程一些awk來使用OR運算符,希望它將計數滿足任一條件的一切:

{ 
count = 0 
$0 = tolower($0) 
while (length() > 0) { 
    m = match($0, /212/ || /121/) 
    if (m == 0) 
     break 
    count++ 
    $0 = substr($0, m + 1) 
} 
print count 
} 

不幸的是,我的輸出是這樣的:

8 
4 
0 
2 
3 

但是,如果我忽略了OR,它會完美計數。我究竟做錯了什麼?

而且,我通過運行在文件中運行ymaz.txt腳本:

cat ymaz.txt | awk -v "pattern=" -f count3.awk 

作爲一種替代方法我試過這樣:

{ 
count = 0 
$0 = tolower($0) 
while (length() > 0) { 
    m = match($0, /212/) 
y = match($0, /121/) 
    if ((m == 0) && (y == 0)) 
     break 
    count++ 
    $0 = substr($0, (m + 1) + (y + 1)) 
} 
print count 
} 

,但我的輸出是這樣的:

1 
1 
0 
1 
1 

我在做什麼錯?我知道我應該理解代碼,而不是剪切和粘貼在一起,但這是我的技能水平。

順便說一句,當我沒有在那裏的OR(即我只是尋找1字符串)它完美的作品。

+2

不是應該'/(212)|(121)/'? – ooga

+0

我在第一行計6場比賽。 – ooga

+1

和第二個5!你應該將其作爲回答@ooga發佈! –

回答

3

你正在做的太複雜了:

{ 
    count=0 
    while (match($0,/121|212/)) { 
     count++ 
     $0=substr($0,RSTART+1) 
    } 
    print count 
} 

$ awk -f tst.awk file 
6 
5 
0 
1 
2 

你的根本問題是,你是混淆了一個正則表達式的條件。一個正則表達式可以與一個字符串進行比較以形成一個條件,並且當所討論的字符串爲$ 0時,您可以將其忽略並僅使用regexp作爲$0 ~ regexp的簡寫,但在此情況下,正在測試的內容仍是條件。匹配()的第二個參數是一個正則表達式,而不是一個條件。 |or運算符的正則表達式,而||or運算符的條件。 /.../是正則表達式分隔符。

/foo/是一個正則表達式

$0 ~ /foo/是在條件環境下的條件

/foo/$0 ~ /foo/速記,但在其他任何情況下僅僅是一個正則表達式。

在有條件的情況下/foo/ || /bar是簡寫$0 ~ /foo/ || $0 ~ /bar/但作爲第二ARG匹配()實際上在awk假設你打算寫:

match($0,($0 ~ /foo/ || $0 ~ /bar/)) 

即它會測試當前記錄與foo或bar的關係,如果爲true,那麼該條件的計算結果爲1,然後將1作爲第二個參數傳給match()。

看:

$ echo foo | gawk 'match($0,/foo/||/bar/)'   
$ echo foo | gawk '{print /foo/||/bar/}' 
1 
$ echo 1foo | gawk 'match($0,/foo/||/bar/)'  
1foo 

拿到書有效AWK編程,第4版,由阿諾德·羅賓斯。

+1

更妙的是,謝謝!由於本主題中的優秀人員已經保存了許多小時。 – Thoughtcraft

3

Perl的方式:

perl -lpe '$_ =() = m/(?=121|212)/go' 

輸出:

6 
5 
0 
1 
2 
相關問題