在终端/ Unix中查找数据列中的唯一元素

时间:2014-07-24 01:14:44

标签: sorting unix

所以,我有一个格式为的数据集:

BBS1    Bbs1    reg 7   Heart
ASAP2   Asap2   reg 5   Heart
SPATA22 Spata22 reg 1   Heart
MYLK4   Mylk4   reg 1   Heart
ATP8A1  Atp8a1  reg 5   Heart

现在器官名称(此处为Heart)可能不同。我有几个关于数据的器官。我想知道如何弄清楚该列的独特元素的名称(第5列)?数据文件很大。

2 个答案:

答案 0 :(得分:5)

如果您只想要第5列中的唯一值,则可以执行以下操作:

awk '{print $5}' inputFile | sort | uniq

或:

awk '{print $5}' inputFile | sort -u

或者,如果您出于某种原因不想使用sort,则可以单独使用awk

awk '{arr[$5] = 1} END {for (key in arr) {print key}}' inputFile

为每一行执行的arr[$5] = 1命令只是使用第5列作为键来更新关联数组。如果该条目不存在,则创建该条目。如果确实存在,则只是被覆盖。

然后,一旦完成文件,就输出该关联数组的所有键。由于创建或覆盖性质,这将是删除重复项的键。

对于一个巨大的文件,从O(n log n)排序切换到O(n)进程可能会加快速度。但是,与所有优化工作一样,测量,不要猜测!


另外,如果您对输入数据有额外的了解,有时可以提高效率。这可能是你的情况,也可能不是这种情况,但我曾经遇到过这样的情况,即数据已经大部分排在(在你的情况下)第5列(想想只是在一个其他排序的器官文件末尾添加条目) )。

这意味着我会得到heart或其他器官的长序列,但偶尔会有这样的混合:

heart
heart
heart
heart
heart
heart
liver
liver
lung
heart    <= What the ?

通过这样的额外信息,您可以加快速度:

awk '{print $5}' | uniq | sort | uniq

现在,可能看起来很奇怪,但输入数据有很长的相同器官这一事实意味着第一个uniq(在O(n)处)大大减少了sort的工作量(最好是O(n log n))。

在上面显示的数据中,sort只需要处理四个项目:

heart    <= uniquified one
liver
lung
heart

而不是十。

最后uniq只是为了清理原始列表中的乱序。

正如我所说,对你来说情况可能并非如此,但有时候在盒子外思考是有利的。

答案 1 :(得分:0)

awk '{print $5}' <file> | sort -u

  

awk {print $5}

将打印数据的第五列

  

sort -u

按字母顺序对数据进行排序,然后只输出唯一元素。