0

共通の列に基づいて複数のファイルをマージする必要がある Perl コードの非常に興味深い部分で立ち往生していますが、この共通の列には異なる数のレコードが含まれています。等々。

例:ここに私の3つのファイルがあります:

FileA.txt

ID  Value
 1   45
 2   56
 3   23

FileB.txt

ID  Value
 2   57
 3   65
 5   32

FileC.txt

ID  Value
 1   21
 3   68
 4   42

私の出力は、次のように結合されたテーブルになるはずです:

ID  ValueA  ValueB  ValueC
 1   45       0      21
 2   56       57     0
 3   23       65     68
 4    0       0      42
 5    0       32     0

使用してみpasteましたが、共通の列を考慮せずに、リストを並べて貼り付けるだけです。

どうすればいいですか?

どんな提案でも大歓迎です。

4

2 に答える 2

1

ハッシュのハッシュを使用して、部分テーブルを記憶します。メインキーは ID で、内部ハッシュのキーはファイルです。

#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);

use Data::Dumper;

my %table;
for my $letter (qw(A B C)) {
    open my $IN, '<', "File$letter.txt" or die "Cannot open: $!";
    <$IN>; # Skip the header
    while (<$IN>) {
        my ($id, $value) = split;
        $table{$id}{$letter} = $value;
    }
}

say "ID\tValueA\tValueB\tValueC";
for my $id (keys %table) {
    say $id, join"\t", q(), map $table{$id}{$_} // 0, qw(A B C);
}
于 2013-01-30T21:23:25.290 に答える
0

(ID をキーとして) ハッシュを初期化し、各ファイルを読み取ることができます。FileA.txt を読むときは、次のように入力します ($id と $value はファイルから取得した値です)。

$my_hash{$id} = {VALUE_A=>$value, VALUE_B=>0, VALUE_C=>0};

各行の FileB.txt を読み取る場合:

if( exists $my_hash{$id} ) {
  $my_hash{$id}->{VALUE_B=>$value};
}
else {
   $my_hash{$id} = {VALUE_A=>0, VALUE_B=>$value, VALUE_C=>0};
}

FileC.txt と非常によく似ています:

if( exists $my_hash{$id} ) {
  $my_hash{$id}->{VALUE_C=>$value};
}
else {
   $my_hash{$id} = {VALUE_A=>0, VALUE_B=>0, VALUE_C=>$value};
}

最後に、すべてのデータが %my_hash にあります

于 2013-01-30T21:17:00.627 に答える