【问题标题】:Creating multiple hashes from multiple files in one go一次从多个文件创建多个哈希
【发布时间】:2018-11-10 08:49:09
【问题描述】:

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

file1: while(){$hash1{$key}=$val}...file2: while(){$hash2{$key}=$val}...file3: while(){$hash3{ $key}=$val}...以此类推

然后打印出来: print "$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...

提前感谢您的帮助和意见

【问题讨论】:

  • 您正在尝试使用符号引用,动态创建变量名;这只是麻烦而且(几乎)从来没有必要。为什么不简单地将这些哈希的引用放在一个数组中?
  • 哈希是由第一个元素的键 ($d[0]) 和......第八个元素的值 ($d[7]) 组成的——这是有意的吗?
  • @zdim...是的,正确理解。每行有 10 列,但我需要从第 1 列(键)和第 7 列(值)中形成散列......是的,符号引用方面确实出现了,但我不确定如何在这里应用它。 .. :(
  • 好的,谢谢。符号参考业务——你不想要它。只是不要这样做。现在,您的解释说“所有文件的第一列的内容(按 n uniq-ed 排序)是参考值”——这是怎么回事?所有文件中的“第一列”是一长串值,这是一个参考吗?你能展示一个样本吗?
  • 好的...现在我有类似的文件:exp1.txt、exp2.txt、exp3.txt 等等。要收集和创建所有参考值的列表,我这样做:cut -f 1 *.txt | sort | uniq &gt; ref_list.txt

标签: perl hash


【解决方案1】:

所示代码尝试使用符号引用在运行时构造变量名。这些东西会引起很多麻烦,不应该使用,除非偶尔在非常专业的代码中。

这是一种读取多个文件的方法,每个文件都放入一个哈希中,并将它们存储起来以供以后处理。

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:,后跟该字符串的值,每个文件一个。

【讨论】:

  • @SangramJB 编辑代码(它在任何空间上拆分,从我的测试来看,现在它使用制表符),并添加了一些注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
  • 2017-04-24
  • 2021-06-19
  • 2015-02-08
  • 2013-07-12
  • 1970-01-01
相关资源
最近更新 更多