2015-04-23 59 views
0

我已經整理文本文件和簡單的awk行只最大值這讓第一線(平均最高值)排序的文件得到

Forexample

Key Column1 Column2 Column3 ..... MaxValue 
Test1 500  400  200    500 
Test1 499  400  200    500 
Test1 499  399  200    499 
Test1 498  100  100    498 
Test2 600  200  150    600 
Test2 600  199  150    600 
Test2 599  199  100    599 

我可以使用shell紙條如下得到動態列

MaxValue=`awk -F'\t' -v OFS="MaxValue" 'NR==1 {for (i=1; i<=NF; i++) if ($i==OFS) {print i} }' 

而且我有簡單的代碼來獲取第一行(平均最大值)

like awk '!a[$1]++' 

那麼結果如下圖所示,

Key Column1 Column2 Column3 ..... MaxValue 
Test1 500  400  200    500 
Test2 600  200  150    600 

由Key剛剛獲得最高值。 但我想檢查另一個動態列,如果相同的值只是打印。 所以下面的結果,

Key Column1 Column2 Column3 ..... MaxValue 
Test1 500  400  200    500 
Test1 499  400  200    500 
Test2 600  200  150    600 
Test2 600  199  150    600 

任何人都有使用awk的好主意嗎? 謝謝!

+0

預期產量是多少?哪些列被排序? – haifzhan

+0

預期輸出是上一個文本,並按MaxValue排序。' –

回答

3

你必須遍歷文件兩次:一次收集極大,一旦發現與它們匹配的行:

awk ' 
    NR == FNR && (!($1 in max) || max[$1] < $NF) {max[$1] = $NF} 
    NR != FNR && $NF == max[$1] 
' file file 

如果你要提供包含您的列名最大值:

awk -v colname="Column2" ' 
    NR == 1 {for (i=2; i<=NF; i++) if ($i == colname) maxcol = i} 
    NR == FNR && (!($1 in max) || max[$1] < $maxcol) {max[$1] = $maxcol} 
    NR != FNR && $maxcol == max[$1] 
' file file 

您可能想要添加一些驗證,即maxcol變量實際設置爲一個數字。


和添加在@ Tommy的建議

awk -v colname="MaxValue" ' 
    NR == 1 { 
    for (i=2; i<=NF; i++) if ($i == colname) maxcol = i 
    print 
    next 
    } 
    (!($1 in max) || max[$1] < $maxcol) { 
    max[$1] = $maxcol 
    n[$1] = 0 
    delete lines[$1] 
    } 
    max[$1] == $maxcol {lines[$1][n[$1]++] = $0} 
    END { for (key in lines) for (i=0; i<n[key]; i++) print lines[key][i] } 
' file 

這一個需要GNU AWK爲數組的數組。

+0

這不是嚴格必須遍歷文件兩次;他可以將相關的行保存在一個數組中並在最後打印。不過,我已經投了你的答案。 –

+1

確實如此,但代碼更多一些(如果最大值發生變化,您必須忘記該鍵的記憶線)。這是性能和可維護性之間的折衷。 –

+0

嗨感謝您的回答,我可以使用動態列值嗎?像awk -v var =「MaxValue」 –