我有这个数据集 - 我只关心类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);
}
答案 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;