qnguyen has asked for the wisdom of the Perl Monks concerning the following question:

I am attempting to pull a number (in my example 1530631) from a line before the line with the beep. * Line that needs to be matched, and I need 1530631. (8/20/09 7:59:28 PM EDT) 1530631: ^^5 * Than I need to match this line and pull this number 1531639. (8/20/09 7:59:28 PM EDT) 1531639: ##Twenty Four;##;pp * I will take the two numbers and subtract them from each other. My current code can only pull the line with the beep, but i cannot figure how to match the line before the beep.
# open a file my $filename = $ARGV[0]; open(debugfile, $filename) || die "Sorry, couldn't open file!"; while($line = <debugfile>) { if($line =~ /##BEEP/) # place the regular expression to match the +first line here { print $line; @firstLine = split(/\)/, $line); $firstLineTime = $firstLine[1]; @match = split (/##/, $firstLineTime); $Tic = $match[0]; $waitingForTargetStatement = 1; # print "$firstLineTime\n"; # print "$Tic\n"; next; } if($line =~ /Pick/ && $waitingForTargetStatement == 1) # place the + regular expression to match the second line here { $waitingForTargetStatement = 0; @secondLine = split(/\)/, $line); $secondLineTime = $secondLine[1]; @match = split (/##/, $secondLineTime); $Tic = $match[0]; $time = $secondLineTime - $firstLineTime; $time = $time/1000; print $line; # print "$Tic\n"; print "The time between the beep and the next pick location is + $time seconds\n"; # modify the print statement print "\n"; next; } # if($line =~ /##|\^\^|SYSMSG|DIALOG/) # place a regular expression + to include other desired content here. # { # print $line; # } }
EXAMPLE OF LOG: (8/20/09 7:59:28 PM EDT) 1524243: ##BEEP (375,2)## (8/20/09 7:59:28 PM EDT) 1524516: ##Two;Five; Pick (8/20/09 7:59:28 PM EDT) 1530337: ^^7 (8/20/09 7:59:28 PM EDT) 1530631: ^^5 (8/20/09 7:59:28 PM EDT) 1531465: ##BEEP (375,2)## (8/20/09 7:59:28 PM EDT) 1531639: ##Twenty Four;##;pp (8/20/09 7:59:44 PM EDT) 1534041: ^^ready (8/20/09 7:59:44 PM EDT) 1534177: ##Three;One; Pick (8/20/09 7:59:44 PM EDT) 1540464: ^^8 (8/20/09 7:59:44 PM EDT) 1540760: ^^8 (8/20/09 7:59:44 PM EDT) 1541590: ##BEEP (375,2)## (8/20/09 7:59:44 PM EDT) 1541884: ##Two;Three; Pick

Replies are listed 'Best First'.
Re: How to match previous line
by moritz (Cardinal) on Aug 26, 2009 at 16:17 UTC
    You need something along the lines of
    use strict; use warnings; my $previous; while (my $line = <$handle>) { if (defined($previous) && $line =~ /BEEP/ ) { print $previous; } $previous = $line; }

    Of course you need additional code to extract the number from $previous, but that doesn't seem to be a problem for you.

    Update: as ambrus++ pointed out in the CB this is a good place to use a continue block for assigning to $previous.

    Perl 6 projects - links to (nearly) everything that is Perl 6.
      Considering that $previous is defined most of the time, it's better to check $line =~ /BEEP/ first. Or just eliminate the check for definedness all together:
      my $previous = ""; while (<$handle>) { print $previous if /BEEP/; $previous = $_; }
      If "BEEP" is on the first line, it just prints nothing. Which is the same effect as not printing (assuming no assignment to $\ has been done).
Re: How to match previous line
by wagnerc (Sexton) on Aug 26, 2009 at 17:05 UTC
    Hi. Three ways to do it.

    One, slurp the file and parse it using subscripts. So when $line[$i] matches, u can pull $line[$i - 1] to get the other value.

    Two, save the current line value into a variable which will be available on the next iteration of the loop.

    while ($line = <FILE>) { if ($line is good) { dosomething($line, $lastline); } $lastline = $line; }

    Three, use Tie::File.