2012-05-24 46 views
2

我有個製表符分隔的文件,該文件是這樣的:UNIQ元素提取

ABCA2 chr9 139021506 139043195 
ABCA2 chr9 139021506 139042561 
ABCC1 chr16 15950934 16144431 
ABCC1 chr16 15950934 16144431 
ABCC1 chr16 15950934 16144431 
ABCC1 chr16 15950934 16144431 

我想根據列來提取值,等ABCA2在2,3列中的值,和4應該提取只有一次,這是名稱第一次出現在column1中。

所需要的輸出是:

ABCA2 chr9 139021506 139043195 
ABCC1 chr16 15950934 16144431 

謝謝

+0

你試過了哪一種python或bash? – Mark

+0

@ khalid:我正在嘗試切割-f1 | uniq ...但在這種情況下不起作用。 – Angelo

+0

這個問題有點令人困惑,因爲你所期望的輸出不是你想要的輸出,你應該輸出文件中的前三行,除非你正在尋找第一次出現在col1中的值以及隨後的數據列包含? –

回答

7

您的問題聲明是模糊的,但我解釋這意味着你只需要一條線,是輸出,如果在入門其第一列尚未見過。我不知道這是爲什麼標籤python,因爲AWK顯然是正確的工具:

awk '{if(!seen[$1]++) print }' input-file 

,或者更簡單地說

awk '! a[$1]++' input-file 
+0

awk'{if(!seen [$ 1] ++)print}'輸入文件這就是我的意思,謝謝 – Angelo

5

使用您的示例輸入file.txtuniq --check-chars=5 file.txt給出了這樣的輸出:

ABCA2 chr9 139021506 139043195 
ABCC1 chr16 15950934 16144431 

正如您所看到的,它僅限於比較每行的前5個字符。

編輯

正如威廉Pursell指出,uniq假定該文件已經排序。另一種方法是使用sort

$ sort --key=1,1 --unique file.txt 
ABCA2 chr9 139021506 139043195 
ABCC1 chr16 15950934 16144431 
$ 

一定要注意以下威廉Pursells評論:排序輸入數據不是絕對必要的規定來解決這個問題。如果速度是一個問題/數據量很大,記憶看到的按鍵的線性解決方案(如威廉姆斯答案中的awk精靈)更好。

+0

請注意,這假設輸入已經排序在第一列 –

+0

@WilliamPursell:這是正確的,謝謝爲了將它拋出。我剛剛用'sort'的例子更新了答案。 –

+1

這是一個美觀的解決方案,但由於它比awk解決方案獲得的票數多,我認爲指出這是不必要的工作。特別是,在我的系統上運行/ usr/share/dict/words上的兩個解決方案時,awk運行速度提高了3倍以上。 –

1
>>> d = {} 
>>> with open('f.txt') as f: 
... for line in f.readlines(): 
...  x = line.split() 
...  if x[0] not in d.keys(): 
...   d[x[0]] = x[1:] 
... 
>>> for k,v in d.iteritems(): 
... print k,' '.join(v) 
... 
ABCA2 chr9 139021506 139043195 
ABCC1 chr16 15950934 16144431