比较同一文件中的多个列

时间:2014-09-16 13:29:12

标签: perl awk

我必须比较两列col1和col2,这样如果A正在发生 与B和再次相同的对发生在B后跟A,它应该 只打印一对以及以下所有列

Input file:
A   B   13.2    0.24    posx    209 215 posy    145 155
B   A   13.2    0.24    posy    145 155 posx    209 215
A   D   19.4    0.28    posx    209 215 posz    366 368


Required output:
A   B   13.2    0.24    posx    209 215 posy    145 155
A   D   19.4    0.28    posx    209 215 posz    366 368

输入文件非常庞大(~10gb)。

3 个答案:

答案 0 :(得分:5)

以下是使用awk的一种方式:

awk '!(a[$1,$2]++ || a[$2,$1]++)' file
A   B   13.2    0.24    posx    209 215 posy    145 155
A   D   19.4    0.28    posx    209 215 posz    366 368

我们使用它们作为数组a的键来跟踪第1列和第2列。只要遇到密钥,++就会增加密钥的值。 ||是一个短路运算符,只有在第一个条件为假时才会触发第二个条件。

我们使用!否定了我们条件的输出。由于awk默认行为是打印真相,我们使用它来避免显式print语句。

答案 1 :(得分:4)

它从每一行获取前两个值,并形成用于过滤掉重复项的排序键,

perl -ane '@k = sort @F[0,1]; $s{"@k"}++ or print' file

输出

A   B   13.2    0.24    posx    209 215 posy    145 155
A   D   19.4    0.28    posx    209 215 posz    366 368

答案 2 :(得分:1)

$ awk '!a[$1,$2];{a[$2,$1]++}' file      
A   B   13.2    0.24    posx    209 215 posy    145 155
A   D   19.4    0.28    posx    209 215 posz    366 368

通常情况a会被命名为seen,但我部分打高尔夫@jaypal的回答,所以需要保持我的击球: - )。

2个答案之间的重要区别在于他们如何处理以与前一行相同的2个键值开头的第二行。 jaypals回答排除了与之前看到的$ 1和$ 2任意顺序匹配的行,因此它会删除重复项,而我的严格遵守已发布的问题,并且只删除之前已经看过反向键的后续行(即当前$ 1 $ 2 =之前的$ 2 $ 1 )。

要增强上述内容以排除重复,可以(作为替代方案):

$ awk '!a[$1,$2]++;{a[$2,$1]++}' file

无论如何,输入中的机会永远不会重复,因此无论哪种方式都无关紧要。