填充多级哈希

时间:2011-07-01 06:17:44

标签: regex perl hash

我有这个数据集 - 我只关心类id,进程@ server: 我试图将所有三个加载到多级哈希。

class_id: 995   (OCAive   )  ack_type: NOACK     supercede:  NO  copy:  NO  bdcst:  NO
PID                                    SENDS   RECEIVES   RETRANSMITS   TIMEOUTS MEAN    S.D.    #
21881  (rocksrvr@ith111          )          1          1             0          0
24519  (miclogUS@ith110          )          1          1             0          0
26163  (gkoopsrvr@itb101          )          1          1             0          0
28069  (sitetic@ith100           )         23          4             0          0
28144  (srtic@ithb10           )         33          5             0          0
29931  (loick@ithbsv115      )          1          1             0          0
87331  (rrrrv_us@ith102          )          1          1             0          0
                                  ---------- ----------    ---------- ---------- ------- ------- ------ 
                                          61         14             0          0

当我尝试填充哈希时,它没有得到太多(下面的数据转储结果)

$VAR1 = '';
$VAR2 = {
    '' => undef
};

这是代码:

#!/usr/bin/perl -w
use strict;
my $newcomm_dir = "/home/casper-compaq/work_perl/newcomm";
my $newcomm_file = "newcomm_stat_result.txt";

open NEWCOMM , "$new_comm_dir$newcomm_file";
while (<NEWCOMM>) {
    if ($_ =~ /\s+class_id:\s\d+\s+((\w+)\s+)/){
        my $message_class = $1;
    }
    if ($_ =~ /((\w+)\@\w+\s+)/) {
        my $process = $1;
    }
    if ($_ =~ /(\w+\@(\w+)\s+)/) {
        my $servers = $1;
    }

    my $newcomm_stat_hash{$message_class}{$servers}=$process;


    use Data::Dumper;
    print Dumper (%newcomm_stat_hash);
}

4 个答案:

答案 0 :(得分:3)

除了声明问题之外,正则表达式还存在多个问题。我建议在尝试将其插入哈希值之前,确保在每个变量中得到预期的输出。

首先,您需要将括号匹配为\(\),否则它们只会被解释为变量容器。

答案 1 :(得分:2)

我在if中的声明只有if作为块的结尾,你的哈希赋值不应该是my。尝试在while循环之前声明%newcomm_stat_hash,并在while块的顶部声明$message_class$process$servers

你也可能想检查一下你的失败;我怀疑你错过了那里。

答案 2 :(得分:1)

您的档案是否已被打开?

我认为你需要改变:

open NEWCOMM , "$new_comm_dir$newcomm_file";

要:

open NEWCOMM , $new_comm_dir.'/'.$newcomm_file;

答案 3 :(得分:1)

我怀疑你的主要错误是你的文件没有打开,因为目录和文件名之间的路径缺少/。您可以使用autodie pragma检查打开成功,或者使用or die "Can't open file: $!"

您有一些范围问题。首先,$message_class将在整个循环中未定义,因为它的范围仅在一次迭代内持续。如果您希望稍后能够使用它,您可能还希望在循环外部使用哈希。

我在标题行检查中放了一个next语句,因为其他检查在该特定行中无效。如果你想更精确,你可以将整个事情放在循环之外,然后进行单行检查。

您不需要为进程和服务器使用这两个变量,只需直接使用它们,并且两者同时使用。

最后,您可能希望将对哈希的引用发送到打印中的Data::Dumper,否则哈希将会扩展,并且打印会有些误导。

#!/usr/bin/perl -w
use strict;
use autodie;
my $newcomm_dir = "/home/casper-compaq/work_perl/newcomm/"; 
my $newcomm_file = "newcomm_stat_result.txt";

open my $fh, '<', "$new_comm_dir$newcomm_file";

my $message_class;
my %newcomm_stat_hash;
while (<$fh>) {
    if (/^\s+class_id:\s+\d+\s+\((\w+)\)\s+/){
        $message_class = $1;
        next;
    }
    if (/(\w+)\@(\w+)/) {
        $newcomm_stat_hash{$message_class}{$2}=$1;
    }
}
use Data::Dumper;
print Dumper \%newcomm_stat_hash;