2016-02-05 32 views
1

最小的10個值我有一個安排,像這樣一個文件:AWK:找到

a 123 
b 45 
c -23 
d 166 

我是新來的awk,我想找到十(或x)最低的列數2並在新文件中打印這些行。

目前我們使用下面的代碼和眼球的結果來看看我們是否大概有十個。如果不是這樣,我們改變了-5.0到別的東西等:

cat input.txt | awk '{if($2 < -5.0) {print $1" "$2}}' >> output.txt 
+1

),你想保留第一個記錄還是最後一個記錄? –

回答

6

您可以輕鬆地做到這一點沒有AWK:

$ sort -nk 2 input.txt | head -10 > output.txt 

它排序輸入文件和打印頭10線(與列2中的最低值)。如果你的輸入文件特別大,這可能不合適。此sort可能使用O(N日誌N)排序算法(對於N輸入行)。


如果您只想要最小值,那麼AWK中的解決方案將是單線程。這種情況有點棘手,因爲你必須保持多個最低值。嘗試是這樣的:

lowest.awk

#!/usr/bin/awk -f 
BEGIN{if (X=="") X=10; s=0} 
{ # insert new value in order 
    for (i=0; i<s && $2>a[i]; ++i); 
    if (s==X && i==s) next 
    for (j=s; j>i; --j) { 
     a[j] = a[j-1] 
     b[j] = b[j-1] 
    } 
    a[i] = $2 
    b[i] = $0 
    if (s<X) s++ 
} 
END{ # print stored lines 
    for (i=0; i<s; ++i) 
     print b[i] 
} 

要在命令行中運行以下命令:

$ awk -f lowest.awk infile.txt > outfile.txt 

您可以指定數量從打印最低值X帶命令行-v X=10

$ awk -v X=10 -f lowest.awk infile.txt > outfile.txt 

但是10是默認值。

這將每個值(在列2中)與數組a的每個元素進行比較,並在需要時插入新值。數組b存儲將在最後打印的實線($0)。 ab的(使用)尺寸是s

通常情況下,你應該通過與類似for (i in a)數組中的條目迭代,但在這種情況下,在a[s]一個額外條目,它必須在打印的結果,因此在ENDfor (i=0; i<s; ++i)格式時,可以忽略不計。

在最壞的情況下,每個Ñ值與在aX值進行比較。所以這是O(XN),這是對O的改進(N日誌Nsort版本。此外,它只需要較少的內存,因爲您只在內存中存儲O(X)值而不是所有N行。

請注意,這通過插入來維護訂單。其中X = N,您將保留所有值並按順序列出它們 - 換句話說,排序。的O(XN)式接近O(Ñ )作爲X接近Ñ,這是一個插入排序算法的複雜性。因此,這AWK版本只比O(ñ日誌ñ)基於排序的方法,即X遠小於ň更有效。

+1

UUoC - 無用的使用「貓」。 'sort'命令將讀取保存將可能大文件壓入兩個管道之一的文件。 –

+0

@JonathanLeffler好點。我剛剛複製了OP的一行。另外值得一提的是,AWK也可以將輸入文件作爲參數。 – e0k

+2

因爲OP做了同樣的事情,所以很容易讓人做不太令人滿意的事情 - 我以類似的方式被抓了很多次。最近更少;我現在知道這個問題。 –

1

@ e0k的sort|head是一般正確的UNIX解決方案,但如果你必須使用AWK出於某種原因,然後用GNU AWK爲sorted_in:如果列表包含多個記錄同一個號碼,(最低的

$ awk -v x=2 '{a[NR]=$2; b[NR]=$0} 
    END{ PROCINFO["sorted_in"]="@val_num_asc"; for (i in a) if (x-->0) print b[i] }' file 
c -23 
b 45 

$ awk -v x=3 '{a[NR]=$2; b[NR]=$0} 
    END{ PROCINFO["sorted_in"]="@val_num_asc"; for (i in a) if (x-->0) print b[i] }' file 
c -23 
b 45 
a 123 
+1

這比我的AWK版本更簡潔(也更容易閱讀)。它基本上和'sort | head'一樣,將整個輸入文件存儲在內存中,對它進行排序,然後打印第一個'x'線。我知道'PROCINFO [「sorted_in」]設置迭代順序,但是AWK什麼時候對它進行排序呢?當你使用'in'時它會對它進行排序嗎?還是它將密鑰放置在一個哈希表中,以便以後可以輕鬆地將它們拉出來?根據它的實現方式,使用散列表來排序可能會很快(但使用更多的內存)。 – e0k

+0

當你執行'in'時,它對它進行排序,因爲直到你設置「sorted_in」,它甚至不知道你想要排序的順序,你可以在實際使用它之前設置20次。您必須檢查gawk手冊和/或聯繫實施人員以獲取更多實施細節。 –