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

I've got a log file I am trying to parse with Perl. Basically I want to select two lines and then concatenate to print out both values on one line.

What I have so far;

#!/usr/bin/perl -w #use strict; my $line1=$_; $LOGFILE="Output.txt"; open(LOGFILE) or die("Could not open Output.txt."); foreach $line1(<LOGFILE>) { if ($line1 =~ m/^Start/) { $time = $line1; } elsif ($line1 =~ m/^Response\s+Time\s+\(avg\):\s+([0-9.]+)/) { $response = $line1; } {print join $time, $response} }

The problem is that I am grabbing each line separately so my result is of the format:

Start: Blah
Response Time Blah

when I want
Start: Blah Response Time Blah

The Response Time line is always 8 lines below the Start line, so I think I could set both variables at the same time if I knew how to tell Perl to search 8 lines below the match.

Replies are listed 'Best First'.
Re: Simple Parsing Script
by roboticus (Chancellor) on Apr 23, 2012 at 19:24 UTC

    swilhelm73:

    If it's always 8 lines after the start line, then go ahead and read a record of 8 lines when you detect start, and then process them as a group:

    if ($line1 =~ m/^Start/) { # Append the rest of the record $line1 .= <LOGFILE> for 1..7; }

    If you care only about the first and last lines, though, you could just skip the intervening lines:

    if ($line1 =~ m/^Start/) { # Skip to the end of the record my $t = <LOGFILE> for 1..6; my $lastline = <LOGFILE>; }

    However, if you simply chomp your input line for the start record, you'll get the single line you want. Note: Some people (myself included) find it more convenient to remove all whitespace from the end of lines using $line =~ s/\s+$//; or equivalent.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Simple Parsing Script
by toolic (Bishop) on Apr 23, 2012 at 19:22 UTC
Re: Simple Parsing Script
by 2teez (Vicar) on Apr 23, 2012 at 20:04 UTC

    Going through your log file with a simple while loop could do this, where any match is attached to a string variable. Check the code below

    #!/usr/bin/perl use warnings; use strict; my $msg = ""; my $log_file = "Output.txt"; open my $fh, '<', $log_file or die "can't open file: $!"; while ( my $line = <$fh> ) { chomp $line; if ( $line =~ /^\bstart.+?/i ) { $msg .= $line. ' '; } elsif ( $line =~ /^\bresponse.+?$/i ) { $msg .= $line. $/; } else { next; } } close $fh or die "can't close file:$!"; print $msg;
      Tweaking the response search term (there is another line with response in it) does the trick. THANK YOU!