我被困在我的Perl代码的一个非常有趣的部分,我必须根据公共列合并多个文件,但是这个公共列包含不同数量的记录,即一些文件可能存在于一个文件中,但是不在其他等等。
例如:以下是我的三个文件:
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
,但只是并排粘贴列表,而不考虑常用列。
我应该怎么做?
任何建议都将不胜感激。
答案 0 :(得分: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);
}
答案 1 :(得分: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
中的所有数据