Uniq元素提取

时间:2012-05-24 11:35:00

标签: bash shell unique

我有一个制表符分隔文件,如下所示:

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

我想基于列提取值,例如第2,3列中ABCA2的值,而4应该只提取一次,这是第一次在column1中出现名称。

理想的输出是:

ABCA2   chr9    139021506   139043195
ABCC1   chr16   15950934    16144431

谢谢

3 个答案:

答案 0 :(得分:7)

您的问题陈述含糊不清,但我将其解释为意味着如果尚未看到第一列中的条目,则只需要输出一行。我不知道为什么这被标记为python,因为awk显然是正确的工具:

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

或者更简单地说

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

答案 1 :(得分:5)

file.txt中使用您的示例输入,uniq --check-chars=5 file.txt提供此输出:

ABCA2 chr9 139021506 139043195
ABCC1 chr16 15950934 16144431

正如您所看到的,它仅限于比较每行的前5个字符。

修改

正如William Pursell所指出的,uniq假定文件已经排序。另一种方法是使用sort

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

请务必注意下面的William Pursells评论:输入数据的排序对于解决上述问题并非绝对必要。如果速度是一个问题/数据量很大,记住看到的键的线性解决方案(例如威廉姆斯答案中的awk灵魂)会更好。

答案 2 :(得分: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