Reputation: 716
I am having the lines of a perforce command execution as follows:
2806 I deep sd_bordeaux 117:02:40 IDLE none
2807 I deep sd_bordeaux 17:02:40 IDLE none
2808 I deep sd_coddeaux 117:02:40 IDLE all
2809 I rahul sd_coddeaux 117:02:40 IDLE all
I have written the following code to run the command to get the above list in $command and store it in a array @lines and use regex to get the specified conditions. But I am not getting the desired results.
my $command = qx |p4 monitor show -ale|;
my $kill_id;
my @lines = split("\n", $command);
for my $line (@lines){
next if not $line =~ /(\d+)\s+/;
my $id = $1;
if ($line =~ /sd_bordeaux\s+(\d+):\d+:\d+\s+/ and $line =~ /IDLE\s+none$/){
my $hours = $1;
print "$hours";
print "\n";
}
}
I am getting an error
Use of uninitialized value $hours in string at ./p4.pl
I am interested in getting the numbers "2806" and "2807" as $id and the first digits "117" & "17" as $hours.
Please can some help me where I am going wrong. Thank you.
Upvotes: 0
Views: 205
Reputation: 109
With data as organised as that, why use a regex at all?
for my $line (@lines) {
my @elems = split /\s+/, $line;
next unless $elems[3] eq "sd_bordeaux";
next unless $elems[-2] eq "IDLE";
next unless $elems[-1] eq "none";
print "$elems[0]\n";
}
Out of interest even if your regex had responded with something, it wouldn't have given you the 280x you're expecting; it would have given you e.g. the 117 part from 117:02:40
If for some reason it's got to be a regex, you could do it with ..
if $line =~ /^(\d+)\s+.s*sd_bordeaux\s+(\d+).*IDLE\snone$/ {
my $id = $1;
my $hours = $2;
... that should at least return the number you're expecting.
Upvotes: 1
Reputation: 385657
$1
contains what was matched by the first capture of the most recent successful regex match.
When you get the error, the most recent successful match was against /IDLE\s+none$/
which contains no captures.
The following would be equivalent:
if ($line =~ /sd_bordeaux\s+(\d+):\d+:\d+\s+/) {
my $hours = $1;
if ($line =~ /IDLE\s+none$/) {
print "$hours\n";
}
}
But it looks like all you need is the following:
if ($line =~ /sd_bordeaux\s+(\d+):\d+:\d+\s+IDLE\s+none$/) {
my $hours = $1;
print "$hours\n";
}
That explains the problem and how to solve it, but Garry provides an alternative approach that's more readable.
Upvotes: 2