如何将共享唯一ID的行合并到逗号分隔表中

时间:2015-07-07 20:33:22

标签: perl awk sed

我想问一些关于如何将共享唯一ID的行合并到逗号分隔表中的提示。 Perl,sed或awk中的任何提示都非常受欢迎。

这就是我现在看到的表格:

protein_id go_id
4102    GO:0003676
4125    GO:0003676
4125    GO:0008270
4139    GO:0008270

这就是我希望转换为:

protein_id  go_id
4102    GO:0003676
4125    GO:0003676, GO:0008270
4139    GO:0008270

3 个答案:

答案 0 :(得分:1)

使用数组的Perl哈希...

#!/usr/bin/perl
use warnings;
use strict;

my %data;
my $header;

while(<DATA>){
    chomp;

    if ($. == 1){
        $header = $_;
        next;
    }
    push @{ $data{(split)[0]} }, (split)[1];
}

print "$header\n";

for my $k (sort {$a<=>$b} keys %data){

    print "$k\t";
    print join(', ', @{ $data{$k} });
    print "\n";
}

__DATA__
protein_id go_id
4102    GO:0003676
4125    GO:0003676
4125    GO:0008270
4139    GO:0008270

答案 1 :(得分:0)

使用awk

<强>输入

$ cat file
protein_id go_id
4102    GO:0003676
4125    GO:0003676
4125    GO:0008270
4139    GO:0008270

输出(如果订单无关紧要)

$ awk 'FNR==1{print;next}{A[$1]=$1 in A ? A[$1]", "$2:$2}END{for(i in A)print i,A[i]}' file
protein_id go_id
4139 GO:0008270
4102 GO:0003676
4125 GO:0003676, GO:0008270

更好的可读版本

awk '
      FNR==1{
              print
              next
            }
            {
              A[$1]=$1 in A ? A[$1]", "$2:$2
            }
         END{
              for(i in A)
                   print i,A[i]
            }
    ' file

输出(如果订单很重要)

$ awk 'FNR==1{print;next}$1 in A{A[$1]=A[$1]", "$2;next}{A[O[++c]=$1]=$2}END{for(i=1; i in O; i++)print O[i],A[O[i]]}' file
protein_id go_id
4102 GO:0003676
4125 GO:0003676, GO:0008270
4139 GO:0008270

更好的可读版本

awk '
     FNR==1{
             print
             next
           }
    $1 in A{
             A[$1]=A[$1]", "$2
             next
           }
           {
            A[O[++c]=$1]=$2
           }
        END{
             for(i=1; i in O; i++)
                  print O[i],A[O[i]]
           }
    ' file

答案 2 :(得分:-1)

$ cat data.txt 
protein_id go_id
4102    GO:0003676
4125    GO:0003676
4125    GO:0008270
4139    GO:0008270
$ perl -aE'sub a{say"$a\t",join", ",@a if$a;@a=($F[1]);$a=$F[0]}$F[0]eq$a?push@a,$F[1]:a()}{a()' data.txt
protein_id      go_id
4102    GO:0003676
4125    GO:0003676, GO:0008270
4139    GO:0008270