一口气从多个文件创建多个哈希

时间:2018-11-10 08:49:10

标签: perl hash

我想执行类似于vlookup的过程,但要处理多个文件,其中所有文件(按n uniq-ed排序)中第一列的内容均为参考值。现在,我想将每个文件中的这些键值对存储在每个哈希中,然后将它们一起打印。像这样:

file1:while(){$ hash1 {$ key} = $ val} ... file2:while(){$ hash2 {$ key} = $ val} ... file3:while(){$ hash3 { $ key} = $ val} ...等等

然后打印:打印“ $ ref_val $ hash1 {$ ref_val} $ hash3 {$ ref_val} $ hash3 {$ ref_val} ...”

$i=1;
@FILES = @ARGV;
foreach $file(@FILES)
{
open($fh,$file);
$hname="hash".$i; ##trying to create unique hash by attaching a running number to hash name
while(<$fh>){@d=split("\t");$hname{$d[0]}=$d[7];}$i++;
}
$set=$i-1;       ##store this number for recreating the hash names during printing

open(FH,"ref_list.txt");
while(<FH>)
{
chomp();print "$_\t";
## here i run the loop recreating the hash names and printing its corresponding value
for($i=1;$i<=$set;$i++){$hname="hash".$i; print "$hname{$_}\t";}
print "\n";
}

现在,我被困在perl的地方以$ hname作为哈希名称,而不是$ hash1,$ hash2 ...

提前感谢您的帮助和意见

1 个答案:

答案 0 :(得分:2)

所示代码尝试在运行时使用符号引用构造变量名称。这些事情可能会带来很多麻烦,因此不应该使用它们,除非在非常专门的代码中偶尔使用。

这是一种读取多个文件的方法,每个文件都存储为哈希,然后将其存储以供以后处理。

use warnings;
use strict;
use feature 'say';

use Data::Dump qw(dd);

my @files = @ARGV;

my @data;
for my $file (@files) {
    open my $fh, '<', $file  or do {
        warn "Skip $file, can't open it: $!";
        next;
    };
    push @data, { map { (split /\t/, $_)[0,6] } <$fh> };
}

dd \@data;

每个哈希将每个列的第一列与第七列(索引6)相关联。由{ }组成的每个文件对此类哈希的引用将添加到数组中。

请注意,当您将键值对添加到已经具有该键的哈希中时,新值将覆盖旧值。因此,如果字符串在文件的第一列中重复,则该文件的哈希将以最后一个的值(列7)结束。 OP不会在数据文件中讨论这种可能的重复项(仅适用于参考文件),请在需要时说明。

Data::Dump仅用于打印;如果您不想安装它,请使用核心Data::Dumper

我不确定是否可以使用该“引用文件”,但是现在您可以遍历每个文件的哈希引用数组,并根据需要获取值。也许像

open my $fh_ref, '<', $ref_file or die "Can't open $ref_file: $!";

while (my $line = <$fh_ref>) {

    my $key = ...   # retrieve the key from $line
    print "$key: ";

    foreach my $hr (@data) {
        print "$hr->{$key} ";
    }
    say '';
}

这将打印key:,后跟该字符串的值,每个文件一个。