0

これは単純な問題ですが、実用的な解決策を見つけることができません。2つのファイルがあり、最初のファイルには、「トマト」、「キュウリ」など、興味のあるすべてのIDが含まれていますが、2番目のファイルには値がない興味のないIDも含まれています。2番目のファイルのデータ構造は次のとおりです

tomato    red

tomato    round

tomato    sweet

cucumber    green

cucumber    bitter

cucumber    watery

取得する必要があるのは、2番目のファイルのすべての一致する値を持つすべてのIDを含むファイルで、次のようにすべてがタブで区切られています。

tomato    red    round    sweet

cucumber    green    bitter    watery   

これまでに行ったことは、最初のファイルのIDからハッシュを作成することです。

 while (<FILE>) {  
     chomp;  
     @records = split "\t", $_; 
     {%hash = map { $records[0] => 1 } @records};
 }

そしてこれは2番目のファイルです:

  while (<FILE2>) {
      chomp;
      @records2 = split "\t", $_; 
      $key, $value = $records2[0], $records2[1];
      $data{$key} = join("\t", $value);
  }

 close FILE;

 foreach my $key ( keys %data )
 {
     print OUT "$key\t$data{$key}\n"
     if exists $hash{$key} 
 }

同じIDに一致するすべての値を組み合わせるためのいくつかの簡単な解決策に感謝します!:)

4

3 に答える 3

1

最初のファイルの場合:

while (<FILE>) {  
    chomp;  
    @records = split "\t", $_; 
    $hash{$records[0]} = 1;
}

そして2番目:

while (<FILE2>) {
    chomp;
    @records2 = split "\t", $_;
    ($key,$value) = @records2;
    $data{$key} = [] unless exists $data{$key};
    push @{$data{$key}}, $value;
}
close FILE;

foreach my $key ( keys %data ) {
    print OUT $key."\t".join("\t", @{$data{$key}})."\n" if exists $hash{$key};
}
于 2012-08-10T11:27:17.613 に答える
0

これは必要なことをするようです

use strict;
use warnings;

my %data;

open my $fh, '<', 'file1.txt' or die $!;
while (<$fh>) {
  $data{$1} = {} if /([^\t]+)/;
}

open $fh, '<', 'file2.txt' or die $!;
while (<$fh>) {
  $data{$1}{$2}++ if /^(.+?)\t(.+?)$/ and exists $data{$1};
}

while ( my ($key, $values) = each %data) {
  print join("\t", $key, keys %$values), "\n";
}

出力

tomato  sweet round red
cucumber  green watery  bitter
于 2012-08-10T20:47:22.247 に答える
-1

最初にデータ マッピングを読むと簡単です。

また、Perl を使用している場合は、最初から Perl の主な強みである CPAN ライブラリを活用することを検討する必要があります。たとえば、ファイルの読み込みはread_file()fromと同じくらい簡単File::Slurpです。自分でファイルを開いたり閉じたりして、while(<>) ループを実行する必要はありません。

use File::Slurp;
my %data;

my @data_lines = File::Slurp::read_file($filename2);
chomp(@data_lines);
foreach my $line (@data_lines) { # Improved version from CyberDem0n's answer
    my ($key, $value) = split("\t", $line);
    $data{$key} ||= []; # Make sure it's an array reference if first time
    push @{ $data{$key} }, $value;
}

my @id_lines = File::Slurp::read_file($filename1);
chomp(@id_lines);
foreach my $id (@id_lines) {
    print join("\t", ( $id, @{ $data{$id} } ) )."\n";
}

少しハックですが、少し短いコードは、最初からデータ ハッシュの値のリストに ID を追加します。

my @data_lines = File::Slurp::read_file($filename2);
chomp(@data_lines);
foreach my $line (@data_lines) { # Improved version from CyberDem0n's answer
    my ($key, $value) = split("\t", $line);
    $data{$key} ||= [ $id ]; # Add the ID for printing
    push @{ $data{$key} }, $value;
}

my @id_lines = File::Slurp::read_file($filename1);
chomp(@id_lines);
foreach my $id (@id_lines) {
    print join("\t", @{ $data{$id} } ) ."\n"; # ID already in %data!
}
于 2012-08-10T13:28:27.393 に答える