【问题标题】:Swapping of columns in a file and remove duplicates交换文件中的列并删除重复项
【发布时间】:2010-04-12 19:38:22
【问题描述】:

我有一个这样的文件:

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

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

term1 term2

term2 term1

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

【问题讨论】:

    标签: linux bash awk


    【解决方案1】:

    使用 perl 对行中的每个单词进行排序和排序很容易。

    ./scriptbelow.pl

    #!/usr/bin/perl
    
    foreach(sort map { reorder($_) } <>) {
        print;
    }
    
    sub reorder {
        return join(' ', sort { $a cmp $b } split(/\s+/, $_)) . "\n";
    }
    

    【讨论】:

      【解决方案2】:

      在 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,第二个调用“排序”命令...

      【讨论】:

        【解决方案3】:

        为了保留原始顺序,awk 中的一个简单(但不一定是快速和/或节省内存的)解决方案:

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

        编辑:ruby 中的排序选项:

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

        【讨论】:

          【解决方案4】:

          如果你想删除 both "term1 term2" 和 "term2 term1":

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

          【讨论】:

            【解决方案5】:
            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】:

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

              【讨论】:

                【解决方案7】:

                我会这样做(如果您不需要保留双列)是:

                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
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-12-03
                  • 2010-11-22
                  • 2016-10-24
                  • 2018-02-10
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多