2016-03-10 42 views
-1

輸入:只有輸出線,如果在特定的列值是唯一

line1 a gh 
line2 a dd 
line3 c dd 
line4 a gg 
line5 b ef 

所需的輸出:

line3 c dd 
line5 b ef 

也就是說,我想輸出線只的情況下,沒有其他產品線包括第2列中的值相同。我認爲我可以通過排序(例如sort -k2,2 input)和uniq的組合來實現這一點,但是看起來,使用uniq我只能從左側跳過列(-f避免比較前N個字段)。當然有一些簡單的方法可以通過awk或其他方法來實現。

+2

你有什麼試過?我們大多數人都很樂意幫助你改進自己的技藝,但不願意擔任短期無償編程人員。在[MCVE](http://stackoverflow.com/help/mcve)中向我們展示您的工作,您期待的結果以及您獲得的結果,我們將幫助您弄清楚。 – ghoti

回答

1

您可以爲一個快速班輪結合的awk,grep的,sort和uniq:

grep -v "^[^ ]* $(awk '{print $2}' input.txt | sort | uniq -d) " input.txt

編輯,避免了正則表達式,\ +和\反向引用:

grep -v "^[^ ]* $(awk '{print $2}' input.txt | sort | uniq -d | sed 's/[^+0-9]/\\&/g') " input.txt

+0

我從來沒有見過像以前那樣使用grep。^[^] *部分是做什麼的? – 5heikki

+0

@ 5heikki第一個'^'將正則表達式錨定在行的前面,第二個'^'匹配不是空格的所有內容。 –

+0

因此,在這種情況下,這將相當於** grep -v「^ [^] * $(echo a)」input **,但是,即使第4列只包含a但仍然有效。我只是不明白爲什麼.. – 5heikki

3

您可以將它作爲一個兩遍awk腳本來執行:

awk 'NR==FNR{a[$2]++;next} a[$2]<2' file file 

這會遍歷文件一旦遞增一個數組中的計數器,其中的鍵是每行的第二個字段,然後再次打印只打印計數器小於2的那些行。

您需要多次讀取文件,因爲在任何在第一次讀取期間,您不可能知道文件後面是否會有該行第二個字段的另一個實例。

1

替代awk來證明它仍然可以通過排序和uniq來完成(這裏有選項-u),但是設置正確的格式需要一些雜耍(裝飾/做東西/未打印模式)。

$ paste file <(cut -d' ' -f2 file) | sort -k2 | uniq -uf3 | cut -f1 

line5 b ef 
line3 c dd 

,你失去了原有的排序順序,可如果添加行號恢復以及副作用...

1

這裏是一個通awk解決方案:

awk '{a1[$2]++;a2[$2]=$0} END{for (a in a1) if (a1[a]==1) print a2[a]}' file 

但是文件的原始順序將會丟失。

+0

不是*完全*一次,是嗎?第一遍從磁盤讀取文件,第二遍從內存讀取文件。 – Graham

+0

@Graham:與'awk'{actions}'文件文件'相反,這將是另一種方式。 – dawg

相關問題