我想执行类似于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 ...
提前感谢您的帮助和意见
答案 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:
,后跟该字符串的值,每个文件一个。