交换文件中的列并删除重复项

时间:2010-04-12 19:38:23

标签: linux bash awk

我有一个这样的文件:

term1 term2
term3 term4
term2 term1
term5 term3
..... .....

我需要做的是按照它们出现的任何顺序删除重复项,例如:

term1 term2

term2 term1

对我而言是重复的。 这是一个非常长的文件,所以我不确定什么可以更快。 有没有人知道如何做到这一点? awk也许吧?

7 个答案:

答案 0 :(得分:1)

使用perl可以轻松排序行中的每个单词并进行排序。

./ scriptbelow.pl< datafile.txt | uniq的

#!/usr/bin/perl

foreach(sort map { reorder($_) } <>) {
    print;
}

sub reorder {
    return join(' ', sort { $a cmp $b } split(/\s+/, $_)) . "\n";
}

答案 1 :(得分:1)

在perl:

while($t=<>) {
 @ts=sort split(/\s+/, $t);
 $t1 = join(" ", @ts);
 print $t unless exists $done{$t1};
 $done{$t1}++;
}

或者:

cat yourfile | perl -n -e  'print join(" ", sort split) . "\n";' | sort | uniq

我不确定哪一个对于大文件表现更好。第一个在内存中生成一个巨大的perl hashmap,第二个调用“sort”命令......

答案 2 :(得分:1)

保留原始排序,awk中的一个简单(但不一定快速和/或内存效率)的解决方案:

awk '!seen[$1 " " $2] && !seen[$2 " " $1] { seen[$1 " " $2] = 1; print }

编辑:在ruby中排序备选方案:

ruby -n -e 'puts $_.split.sort.join(" ")' | sort | uniq

答案 3 :(得分:1)

如果文件很长,也许您应该考虑用C / C ++编写程序。我认为这将是最快的解决方案(特别是如果您必须处理您阅读的每一行的所有文件)。使用bash函数进行处理对于大文件和重复操作来说非常慢

答案 4 :(得分:1)

如果你想删除“term1 term2”和“term2 term1”:

join -v 1 -1 1 <(sort input_file) -v 2 -2 2 <(sort -k 2 input_file) | uniq

答案 5 :(得分:1)

awk '($2FS$1 in _){
 delete _[$1FS$2];delete _[$2FS$1]
 next
} { _[$1FS$2] }
END{ for(i in _)  print i } ' file

输出

$ cat file
term1 term2
term3 term4
term2 term1
term5 term3
term3 term5
term6 term7

$ ./shell.sh
term6 term7
term3 term4

答案 6 :(得分:1)

我这样做的方式(如果你不需要保留双列)是:

sed 's/ /\n/g' test.txt | sort -u

这是输出的样子(忽略我的时髦提示):

[~]
==> cat test.txt
term1 term2
term3 term4
term2 term1
term5 term3
[~]
==> sed 's/ /\n/g' test.txt | sort -u
term1
term2
term3
term4
term5