2010-10-29 24 views
2

我有這樣的文字: 如何使用awk打印行,僅當其右半部分_doesn't_與前一行的右半部分匹配時纔打印行?

 
[100 ps] bar 
[139 ps] foo de fa fa 
[145 ps] foo de fa fa 
[147 ps] foo de fa fa 
[149 ps] le pamplemouse 
[150 ps] le pamplemouse 
[177 ps] le pomme de terre 
[178 ps] le pomme de terre 

在awk中我想篩選出其中的所有行的右半前行的右半部分匹配的線。即如同沒有時間戳那樣的唯一化行。所以我想尼克斯:

 
    [100 ps] bar 
    [139 ps] foo de fa fa 
    [145 ps] foo de fa fa <-- Nuked 
    [147 ps] foo de fa fa <-- Nuked 
    [149 ps] le pamplemouse 
    [150 ps] le pamplemouse <-- Nuked 
    [177 ps] le pomme de terre 
    [178 ps] le pomme de terre <-- Nuked

給我的輸出:

 [100 ps] bar 
    [139 ps] foo de fa fa 
    [149 ps] le pamplemouse 
    [177 ps] le pomme de terre

如何才能做到這一點?

編輯: 對不起,我沒有我應該清楚。字符串的左半部分是一個具有固定數量標記的時間戳,但右半部分會有許多標記。一般情況下,我可以創建任意內存分組,如:

(regex1)(regex2) 

然後比較$2,其中$2是匹配regex2行的一部分嗎?

回答

1

Running on ideone:

BEGIN {prev=""} 

$3==prev {next} 

{ prev = $3; 
print;} 
+0

你能概括這個解決方案,其中字符串的左半部分和右半部分由正則表達式定義? – 2010-10-29 23:56:13

+0

@Ross請問你可以在你的問題中加上一個例子嗎? – 2010-10-30 00:03:20

+0

我得到了我想操作字段分隔符的地方,因爲字符串的中間部分是常量:''BEGIN {FS =「ps L fc」; ...''。 – 2010-10-30 00:03:26

1

您可以使用associative arrays爲右側的每個鍵保留一個計數器。

這是一個概念,一個襯墊的證明,就可以作爲一個起點

$ echo "[100 ps] bar\n[139 ps] foo\n[140 ps] foo" | 
    awk '{count[$3]++; if (count[$3] == 1) print;}' 
[100 ps] bar 
[139 ps] foo 

這將不得不進行調整,如果右邊的字符串可以包含空格使用。

1

什麼是正確的一半來自左半部分分開?它是一個製表符還是多個空格?如果它是那麼標籤:

awk -F '\t' ' 
    $2 in seen {next} 
    { print; seen[$2]=1 } 
' 

否則,我喜歡寫東西

perl -ane ' 
    $right_half = join " ", @F[2..-1]; 
    if (not $seen{$right_half}) { 
     print; 
     $seen{$right_half} = 1; 
    } 
' 
1
$ awk -F"][ \t]+" '!a[$2]++' file 
[100 ps] bar 
[139 ps] foo de fa fa 
[149 ps] le pamplemouse 
[177 ps] le pomme de terre