Perlを使用して、列に基づいて3つのファイルを比較します。

Perlを使用して、列に基づいて3つのファイルを比較します。

3つのファイルがあり、ファイル1の最初の列をファイル2の最初の列と一致させ、次にファイル1の2番目の列をファイル3の最初の列と一致させる必要があります。

  • ファイル1には次の行などが含まれています。

    • fji01dde AIDJFMGKG  
      dlp02sle VMCFIJGM
      cmr03lspCKEIFJ
      
  • ファイル2には、次の行などが含まれています。

    • fji01dde 25 30  
      dlp02sle 40 50  
      cmr03lsp 60 70  
      
  • ファイル 3 には以下が含まれます。

    • エッジ付き FMGKG  
      CKEIFJ  
      
  • 私の予想結果は次のとおりです。

    • fji01dde AIDJFMGKG 25 30  
      cmr03lsp CKEIFJ 60 70  
      
    • など...

  • 3つのファイルすべてに共通の行だけが必要ですが、実行すると...

    • #!/usr/bin/env perl
      use strict;
      use warnings;
      my %data;
      
      while (<>) {  
          my ( $key, $value ) = split;  
          push( @{ $data{$key} }, $value );  
      }  
      
      foreach my $key ( sort keys %data ) {  
          if ( @{ $data{$key} } >= @ARGV ) {  
          print join( "\t", $key, @{ $data{$key} } ), "\n";  
          }    
      }
      
    • 私の結果は...

    • エッジ付き FMGKG  
      CKEIFJ  
      fji01dde 25  
      dlp02sle 40  
      cmr03lsp 60
      

どんなアイデアがありますか?よろしくお願いします!

ベストアンサー1

while(<>)スクリプトの主な問題は、ループの終わりに@ARGVが空になることです。ループを実行する前に、パラメータの数を取得する必要があります。 Perl配列は0から始まるので、数から1を引く必要があることを覚えておいてください。

これは要求された出力を生成する修正版です。

$ cat compare.pl 
#!/usr/bin/perl
use strict;
use warnings;

my $numargs=@ARGV-1;
my %data=();

while (<>) {  
    my ( $key, $value ) = split;  
    push( @{ $data{$key} }, $value );  

}  

foreach my $key ( sort keys %data ) {  
    if ( @{ $data{$key} } >= $numargs ) {  
    print join( "\t", $key, @{ $data{$key} } ), "\n";  
    }  
}

$ ./compare.pl file1 file2 file3
cmr03lsp    CKEIFJ  60
dlp02sle    VMCFIJGM    40
fji01dde    AIDJFMGKG   25

おすすめ記事