Reputation: 387
Ok, I have the following hash and am trying to match the referenced element:
$VAR1 = {
'743' => '00:1',
'20687' => '01:3',
};
Could someone tell me how do I check to see if the value '00:1' (as an example) matches another variable? This is what I currently have and is not working:
if($pids{$pid} == qr/$time/){
$pids{$pid}{$time}[$y] = $line;
$y++;
};
I've also tried if(exists($pids{$pid}{$time}))
and a few others.
UPDATE
Pertaining to the questions below, pids is a hash, %pids.
This is how the hash table comes out when I run it without matching to $time which is exactly what I want:
$VAR1 = {
'743' => '00:1',
'4771' => {
'23:5' => [
'Dec 1 23:59:23 ftp1 ftpd[4771]: USER test
',
'Dec 1 23:59:23 ftp1 ftpd[4771]: PASS password
',
'Dec 1 23:59:23 ftp1 ftpd[4771]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], test
',
'Dec 1 23:59:23 ftp1 ftpd[4771]: CWD /home/test/
',
'Dec 1 23:59:23 ftp1 ftpd[4771]: TYPE Image
',
'Dec 1 23:59:23 ftp1 ftpd[4771]: PASV
',
'Dec 1 23:59:23 ftp1 ftpd[4771]: RETR test
',
'Dec 1 23:59:23 ftp1 ftpd[4771]: QUIT
',
'Dec 1 23:59:23 ftp1 ftpd[4771]: FTP session closed
'
]
},
Here's an example of the data that would come through:
Dec 1 23:59:03 ftp1 ftpd[4771]: USER test
Dec 1 23:59:03 ftp1 ftpd[4771]: PASS password
Dec 1 23:59:03 ftp1 ftpd[4771]: FTP LOGIN FROM 192.168.0.02 [192.168.0.2], test
Dec 1 15:02:03 ftp1 ftpd[4771]: CWD /home/test # Looks same but different time so not a match
Dec 1 23:59:03 ftp1 ftpd[4771]: CWD /home/test
Dec 1 23:59:03 ftp1 ftpd[4771]: TYPE Image
So as you can see above, I could have two lines with different "pids", I only want to match the one of those times, not both.
If you need more info on this, I have all the details in another question I have open but seems to be dead in the water: Playing with Hashes from a FTP flow in Perl
Upvotes: 0
Views: 192
Reputation: 57600
If you can extract the $time
from each line, this is easy:
use strict;
use warnings;
use Data::Dump;
my %pids;
while (my $line = <>) {
chomp $line;
my ($time, $pid) = $line =~ /([0-9]{1,2}:[0-9]) .*? \[([0-9]+)\] /x or next;
push @{ $pids{$pid}{$time} }, $line;
}
dd \%pids;
__DATA__
Dec 1 23:59:03 ftp1 ftpd[4771]: USER test
Dec 1 23:59:03 ftp1 ftpd[4771]: PASS password
Dec 1 23:59:03 ftp1 ftpd[4771]: FTP LOGIN FROM 192.168.0.02 [192.168.0.2], test
Dec 1 15:02:03 ftp1 ftpd[4771]: CWD /home/test # Looks same but different time so not a match
Dec 1 23:59:03 ftp1 ftpd[4771]: CWD /home/test
Dec 1 23:59:03 ftp1 ftpd[4771]: TYPE Image
Dec 2 23:12:03 ftp1 ftpd[1234]: USER test
Dec 2 23:12:03 ftp1 ftpd[1234]: PASS password
Dec 2 23:12:03 ftp1 ftpd[1234]: CWD /home/test
which would produce the following output:
{
1234 => {
"23:1" => [
"Dec 2 23:12:03 ftp1 ftpd[1234]: USER test",
"Dec 2 23:12:03 ftp1 ftpd[1234]: PASS password ",
"Dec 2 23:12:03 ftp1 ftpd[1234]: CWD /home/test ",
],
},
4771 => {
"15:0" => [
"Dec 1 15:02:03 ftp1 ftpd[4771]: CWD /home/test # Looks same but different time so not a match ",
],
"23:5" => [
"Dec 1 23:59:03 ftp1 ftpd[4771]: USER test",
"Dec 1 23:59:03 ftp1 ftpd[4771]: PASS password ",
"Dec 1 23:59:03 ftp1 ftpd[4771]: FTP LOGIN FROM 192.168.0.02 [192.168.0.2], test ",
"Dec 1 23:59:03 ftp1 ftpd[4771]: CWD /home/test ",
"Dec 1 23:59:03 ftp1 ftpd[4771]: TYPE Image",
],
},
}
If you are only interested in a predefined set of PIDs and times, you could perhaps do something like:
my %pids = (
5678 => { '00:1' => [] },
4771 => { '23:5' => [] },
);
while (my $line = <>) {
chomp $line;
my ($time, $pid) = $line =~ /([0-9]{1,2}:[0-9]) .*? \[([0-9]+)\] /x or next;
if (exists $pids{$pid} and exists $pids{$pids}{$time}) {
push @{ $pids{$pid}{$time} }, $line;
}
}
or
my %times;
@times{qw/ 00:01 23:5 /} = ();
...
push @{ $pids{$pid}{$time} }, $line if exists $times{$time};
If there is no way to extract the time from the line in a general manner, you could match all possible times:
my %pids = (
5678 => { '00:1' => [] },
4771 => { '23:5' => [] },
);
while (my $line = <>) {
chomp $line;
my ($pid) = $line =~ /\[([0-9]+)\]/ or next;
next if not exists $pids{$pid};
my $time_regex = join '|', map quotemeta, keys %{ $pids{$pid} };
my ($time) = $line =~ /($time_regex)/ or next;
push @{ $pids{$pid}{$time} }, $line;
}
Upvotes: 1