I have this data set - I am only concerned with the class id, the process@server: I am trying to load all three into a multi-level hash.
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@it开发者_运维知识库h102 ) 1 1 0 0
---------- ---------- ---------- ---------- ------- ------- ------
61 14 0 0
When i try and populate the hash, it does not get much (data dumper results below)
$VAR1 = '';
$VAR2 = {
'' => undef
};
This is the code:
#!/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);
}
Apart from the declarations problem, there are also multiple problems with your regex expressions. I would suggest making sure you get the expected output into each of the variables prior to trying to insert it into a hash.
For one thing you need to match parenthesis as \(
, \)
otherwise they are just interpreted as variable containers.
Your my declarations inside the if only have scope until the end of the if block, and your hash assignment shouldn't have a my. Try declaring %newcomm_stat_hash
before the while loop and $message_class
, $process
, and $servers
at the top of the while block.
You also probably want to check your open for failure; I suspect you are missing a / there.
I suspect your main error is that your file is not opened, due to the path missing a /
, between directory and filename. You can use the autodie pragma to check that the open succeeds, or you can use or die "Can't open file: $!"
.
You have some scope issues. First off, $message_class
will be undefined throughout the loop, since it's scope lasts only inside one iteration. You probably also want to have the hash outside the loop, if you want to be able to use it later on.
I put a next
statement in the header line check, as the other checks will be invalid in that particular line. If you want to be more precise, you can put the whole thing outside the loop, and just do a single line check.
You do not need the two variables for process and server, just use them directly, and both at the same time.
Lastly, you probably want to send the reference to the hash to Data::Dumper
in the print, else the hash will expand, and the print will be somewhat misleading.
#!/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;
Is your file being opened?
I think you need to change:
open NEWCOMM , "$new_comm_dir$newcomm_file";
To:
open NEWCOMM , $new_comm_dir.'/'.$newcomm_file;
精彩评论