【问题标题】:Conversion of multi column to row with reference to first column? [closed]参考第一列将多列转换为行? [关闭]
【发布时间】:2014-06-07 09:38:47
【问题描述】:

这是我的文件 A

NoARTInfo_6 hm_database_atg_all bil|qw_N_g8589t1
NoARTInfo_6 alia_query_atg_all  alia|FBgn0028542
NoARTInfo_7 hm_database_atg_all bil|qw_N_g7396t1
NoARTInfo_7 alia_query_atg_all  alia|rmt0034647
WTCArcNu8_1 req_query_atg_all req|nbrL2EG020589
WTCArcNu21_1  hm_database_atg_all bil|qw_N_g5599t1
WTCArcNu21_1  req_query_atg_all req|nbrL2EG004245

我想把文件转换成文件 B,看起来像

NoARTInfo_6 hm_database_atg_all bil|qw_N_g8589t1 alia_query_atg_all alia|FBgn0028542
NoARTInfo_7 hm_database_atg_all bil|qw_N_g7396t1  alia_query_atg_all  alia|rmt0034647
WTCArcNu8_1 req_query_atg_all req|nbrL2EG020589
WTCArcNu21_1  hm_database_atg_all bil|qw_N_g5599t1 req_query_atg_all  req|nbrL2EG004245

第一列有一些重复的标识符(这里是NoARTInfo_6NoARTInfo_7NoARTInfo_6)和一些唯一的标识符(这里是NoARTInfo_6)。

第二列和第三列有它们的值。

如果第一列 id 重复,那么它们应该只在文件 B 中出现一次,其中包含所有值。

【问题讨论】:

  • 你有什么问题?
  • 请出示您的代码并描述您遇到的问题

标签: perl bash shell awk grep


【解决方案1】:

这个 awk 应该可以工作:

awk '!a[$1]{b[++n]=$1; a[$1]=$0; next} {k=$1; $1=""; a[k] = a[k] $0}
     END{for (i=1; i<=n; i++) print a[b[i]]}' file
NoARTInfo_6 hm_database_atg_all bil|qw_N_g8589t1 alia_query_atg_all alia|FBgn0028542
NoARTInfo_7 hm_database_atg_all bil|qw_N_g7396t1 alia_query_atg_all alia|rmt0034647
WTCArcNu8_1 req_query_atg_all req|nbrL2EG020589
WTCArcNu21_1  hm_database_atg_all bil|qw_N_g5599t1 req_query_atg_all req|nbrL2EG004245

【讨论】:

    【解决方案2】:
    #!/usr/bin/perl
    use strict;
    use warnings;
    my %hash;
    open (my $fh, "<", "fileA") or die $!;  #Open fileA in read mode
    open (my $fh2, ">", "fileB") or die $!; #Open fileB in write mode
    while(chomp(my $line=<$fh>)){
        my ($key, @values) = split / /, $line;
        if(exists $hash{$key}){
           my $ref_value = $hash{"$key"};
           push @values, @$ref_value;
           $hash{"$key"} = [@values];   
        }
         else{
           $hash{"$key"} = [@values];
        }
    }
    foreach(keys %hash){
        print $fh2 "$_ @{$hash{$_}}\n"; #Write to fileB
    }
    close($fh);
    close($fh2);
    

    更短:

    #!/usr/bin/perl
    # your code goes here
    use strict;
    use warnings;
    my %hash;
    open (my $fh, "<", "fileA") or die $!;  #Open fileA in read mode
    open (my $fh2, ">", "fileB") or die $!; #Open fileB in write mode
    while(chomp(my $line = <$fh>)){
        my ($k, @vals) = split / /, $line;
        push @{ $hash{$k} }, @vals;
    }
    foreach(keys %hash){
        print $fh2 "$_ @{$hash{$_}}\n"; #Write to fileB
    }
    

    【讨论】:

      【解决方案3】:
      #!/usr/bin/perl
      
      while (<>) {
        my ($key, @list) = split;
        push(@keys, $key) if !defined $hash{$key};
        push(@{$hash{$key}}, @list);
      }
      foreach (@keys) {
        print join(' ', ($_, @{$hash{$_}})), "\n";
      }
      

      输出

      ./script.pl data
      NoARTInfo_6 hm_database_atg_all bil|qw_N_g8589t1 alia_query_atg_all alia|FBgn0028542
      NoARTInfo_7 hm_database_atg_all bil|qw_N_g7396t1 alia_query_atg_all alia|rmt0034647
      WTCArcNu8_1 req_query_atg_all req|nbrL2EG020589
      WTCArcNu21_1 hm_database_atg_all bil|qw_N_g5599t1 req_query_atg_all req|nbrL2EG004245
      

      我不确定行的顺序是否重要,但无论如何我都保留了它。

      【讨论】:

        猜你喜欢
        • 2022-10-13
        • 1970-01-01
        • 2015-06-13
        • 1970-01-01
        • 2022-11-17
        • 2019-03-27
        相关资源
        最近更新 更多