我必须比较两列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)。
答案 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
无论如何,输入中的机会永远不会重复,因此无论哪种方式都无关紧要。