0

我被 Perl 代码的一个非常有趣的部分困住了,我必须基于一个公共列合并多个文件,但是这个公共列包含不同数量的记录,即一些记录可能存在于一个文件中,但不存在于其他文件中等等。

例如:这是我的三个文件:

文件A.txt

ID  Value
 1   45
 2   56
 3   23

文件B.txt

ID  Value
 2   57
 3   65
 5   32

文件C.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 回答