Bash Uniq元素提取
我有一个以制表符分隔的文件,如下所示:Bash Uniq元素提取,bash,shell,unique,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 我想根据列
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和4中的ABCA2
的值应该只提取一次,这是名称第一次出现在列1中
理想的产出是:
ABCA2 chr9 139021506 139043195
ABCC1 chr16 15950934 16144431
谢谢关于您的问题的陈述模棱两可,但我的解释是,您只希望在第一列中的条目尚未被看到时输出一行。我不知道为什么将其标记为python,因为awk显然是正确的工具:
awk '{if( !seen[$1]++ ) print }' input-file
或者,更简单地说
awk '! a[$1]++' input-file
使用
file.txt
中的示例输入,uniq--check chars=5 file.txt
给出以下输出:
ABCA2 chr9 139021506 139043195
ABCC1 chr16 15950934 16144431
正如您所见,它仅限于比较每行的前5个字符
编辑:
正如William Pursell指出的,uniq
假定文件已经排序。另一种方法是使用排序:
$ sort --key=1,1 --unique file.txt
ABCA2 chr9 139021506 139043195
ABCC1 chr16 15950934 16144431
$
请务必注意下面的William Pursells评论:严格来说,解决上述问题并不需要对输入数据进行排序。如果速度是一个问题/数据量很大,那么线性解决方案(如威廉姆斯答案中的awk
soultion)会更好。你试过python或bash中的哪一种?@khalid:我试过cut-f1 | uniq。。。但在这种情况下它不起作用。这个问题有点让人困惑,因为你想要的输出不是你想要的,你的文件中的前3行应该被输出,除非你要寻找col1中第一个出现的值以及它包含的后续数据列?@christian:我已经编辑了这个问题。awk'{if(!已看到[$1]++)打印}'输入文件这就是我的意思,谢谢不要假设输入已经在第一个column@WilliamPursell:这是正确的,谢谢你指出它。我刚刚用一个例子更新了答案,使用了排序
。这是一个美观的解决方案,但由于它比awk解决方案获得了更多的选票,我认为很高兴指出排序是不必要的工作。特别是在我的系统上运行/usr/share/dict/words上的两个解决方案时,awk的运行速度快了3倍多。
>>> 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