2017-10-07 132 views
-1

我想根據出場次數對輸入進行排序。但是,我不想刪除唯一或非唯一的行。舉例來說,如果我得到以下輸入:如何根據出現的UNIX數量對行進行排序?

Not unique 
This line is unique 
Not unique 
Also not unique 
Also unique 
Also not unique 
Not unique 

我會找一組流水線的命令,可輸出以下會:

This line is unique 
Also unique 
Also not unique 
Also not unique 
Not unique 
Not unique 
Not unique 

感謝您的幫助,您可以提供,我一直在嘗試使用不同的獨特和排序組合,但無法弄清楚,解決方案最好是單線程。

更新:謝謝所有回覆的人,尤其是@batMan,他的回答正是我用我熟悉的命令尋找的。

我仍在試圖學習如何管道和使用多個命令看似簡單的任務,所以我可能適應他的答案與2列工作?例如,如果原始輸入過:

Notunique dog 
Thislineisunique cat 
Notunique parrot 
Alsonotunique monkey 
Alsounique zebra 
Alsonotunique beaver 
Notunique dragon 

而且我想要的輸出進行排序的第一列像這樣:

Thislineisunique cat 
Alsounique zebra 
Alsonotunique monkey 
Alsonotunique beaver 
Notunique dog 
Notunique parrot 
Notunique dragon 

謝謝大家的是提前這麼有用!

+0

你能證明你有什麼嘗試到目前爲止?我會使用一個簡短的Python腳本,使用'collections.Counter'可以非常簡短,但這對純粹的'shell'解決方案不起作用。 – norok2

回答

0

uniq + sort + grep溶液:

擴展inputfile內容:

Not unique 
This line is unique 
Not unique 
Also not unique 
Also unique 
Also not unique 
Not unique 
Also not unique 
Also not unique 

排序初始文件事先:

sort inputfile > /tmp/sorted 

uniq -u /tmp/sorted; uniq -dc /tmp/sorted | sort -n | cut -d' ' -f8- \ 
    | while read -r l; do grep -x "$l" /tmp/sorted; done 

輸出:

Also unique 
This line is unique 
Not unique 
Not unique 
Not unique 
Also not unique 
Also not unique 
Also not unique 
Also not unique 

----------

您也可以包圍整個工作分爲bash腳本:

#!/bash/bash 

sort "$1" > /tmp/sorted # $1 - the 1st argument (filename) 
uniq -u /tmp/sorted 

while read -r l; do 
    grep -x "$l" /tmp/sorted 
done < <(uniq -dc /tmp/sorted | sort -n | cut -d' ' -f8-) 
+0

這不會按出現次數排序,它只是首先放入獨特的行(排序),非唯一行按字母順序排序,而不是按頻率排序。如果輸入中還有幾行'也不是唯一的',它應該顯示在輸出結尾,但不適用於此解決方案。 –

+0

只需使用這個作爲你的輸入文件,每個字符在一個單獨的行上:'A A B B B B C C C'。顯然,按頻率排序,這或者必須變成「A A C C C B B B B」或者逐漸減少「B B B C C C A A」,但它將是未經修改的輸入。 'uniq'不重新排列它的輸入,只是對它進行過濾。 –

+0

@BenjaminW。,好吧,檢查我的更新 – RomanPerekhrest

0

我會用awk計數的次數每個線路中發生數,然後打印出來(預先計劃通過頻率)和排序數值使用sort -n

awk 'FNR==NR{freq[$0]++; next} {print freq[$0],$0}' data.txt data.txt | sort -n 

樣本輸出

1 Also unique 
1 This line is unique 
2 Also not unique 
2 Also not unique 
3 Not unique 
3 Not unique 
3 Not unique 

這真是一個施瓦茨變換。如果您想放棄主頻列,只需在該命令的末尾添加| cut -d ' ' -f 2-即可。

1

awk單獨將是最適合您的更新問題。

$ awk '{file[$0]++; count[$1]++; max_count= count[$1]>max_count?count[$1]:max_count;} END{ k=1; for(n=1; n<=max_count; n++){ for(i in count) if(count[i]==n) ordered[k++]=i} for(j in ordered) for(line in file) if (line~ordered[j]) print line; }' file 

Alsounique zebra 
Thislineisunique cat 
Alsonotunique beaver 
Alsonotunique monkey 
Notunique parrot 
Notunique dog 
Notunique dragon 

說明:

部分-1:

{file[$0]++; count[$1]++; max_count= count[$1]>max_count?count[$1]:max_count;}

我們在存儲陣列file輸入文件; count數組會跟蹤每個唯一第一個字段的計數,這是您希望對文件進行排序的基礎。 max_count跟蹤最大數量。

部分-2: 一旦AWK讀完文件中,count內容將是如下:如圖所示(鍵,值)

Alsounique 1 
Notunique 3 
Thislineisunique 1 
Alsonotunique 2 

現在我們的目標是通過數值這些鍵進行排序下面。這是我們關鍵的一步,對於下面輸出中的每個字段/鍵/列1,我們將遍歷file數組並打印包含這些鍵的行,它會給我們提供最終所需的輸出。

Alsounique 
Thislineisunique 
Alsonotunique 
Notunique 

下面迴路確實存儲另一個陣列count陣列的內容的操作在sorted by values方式稱爲orderedordered的內容將與上面顯示的輸出相同。

for(n=1; n<=max_count; n++) 
    { 
     for(i in count) 
      if(count[i]==n) 
      ordered[k++]=i 
    } 

的最後一步:即遍歷file陣列和存儲在ordered陣列的字段的順序打印的行。

for(field in ordered) 
    for(line in file) 
     if (line~ordered[field]) 
      print line; 
    } 

溶液-2
另一可能的解決方案將使用排序uniq的AWK /切割。但是如果你的輸入文件非常大,我不會推薦使用它,因爲多個管道調用多個進程會減慢整個操作。

$ cut -d ' ' -f1 file | sort | uniq -c | sort -n | awk 'FNR==NR{ordered[i++]=$2; next} {file[$0]++;} END{for(j in ordered) for(line in file) if (line~ordered[j]) print line;} ' - file 
Alsounique zebra 
Thislineisunique cat 
Alsonotunique beaver 
Alsonotunique monkey 
Notunique parrot 
Notunique dog 
Notunique dragon 

以前的解決方案(OP編輯之前的問題)

這可以通過使用sortuniqawk這樣進行:

$ uniq -c <(sort f1) | sort -n | awk '{ for (i=1; i<$1; i++){print}}1' 
     1 Also unique 
     1 This line is unique 
     2 Also not unique 
     2 Also not unique 
     3 Not unique 
     3 Not unique 
     3 Not unique 
+0

非常感謝你的這一切,它完成了我正在尋找的東西!我仍然試圖學習如何管理和使用多個命令來完成看起來很簡單的任務,所以我可以使它適應兩列工作嗎?例如,如果原始輸入已經 Notunique 1 Thislineisunique 2 Notunique 3 Alsonotunique 4 Alsounique 5 Alsonotunique 6 不是唯一7 而我想輸出要由第一列像這樣 Thislineisunique 2 排序Alsounique 5 Alsonotunique 4 Alsonotunique 6 Notunique 1 Notunique 3 Notunique 7 其中數字是隻表示任何文本 – trysofter

+0

我編輯原來的職位,因此以前的評論是我n更好的格式,再次感謝你! – trysofter

+0

第一列在您的方法中是多餘的 – RomanPerekhrest

相關問題