in reply to Print 5 lines before and after pattern match from a list

Here's a filter version (read from stdin, write to stdout) of this, um, filter. I've also added the before/after context parameters as program options. (Consistent with the grep utility.)

Note the use of a small queue (@lines) to buffer the before-context. And notice the versatility of the splice function.

#!/usr/bin/env perl use strict; use warnings; use Getopt::Std; my @patterns = ( qr/error/i, qr/FATAL/, qr/Critical/, qr/exception/, ); my $re = join '|', @patterns; my %opt = ( B => 5, A => 5 ); getopts('B:A:', \%opt); my $window = $opt{B} + $opt{A} + 1; my $emit = 0; my @lines; while (<>) { $emit = $window if /$re/; splice(@lines, 0, 0, $_); --$emit < 0 ? splice(@lines, $opt{B}) : print splice(@lines, -1); }
Edit: above code is deficient both at the start and end of the stream. See if you can fix it...

Replies are listed 'Best First'.
Re^2: Print 5 lines before and after pattern match from a list
by ww (Archbishop) on Mar 15, 2015 at 16:00 UTC

    I don't think the attribute "deficient" applies so much to your code as to OP's imperfect spec. Clearly, if an element of @patterns occurs in first line of the log being read, lines ( -n .. 0 ) simply do NOT exist (for any value other than 0 of the prior lines desired). We can speculate, but OP alone knows (or 'should know') the complete spec.

    Similarly, if any element of @patterns occurs in the last line, the lines ( (last+1)..(last+5) ) are going to be a bit difficult to include in the output.

    BUT, far more important than the observations above, your code (Re: Print 5 lines before and after pattern match from a list) and that above same title, different node, by bitingduck are excellent examples of what Monks can do to help a Seeker, as is hdb's initial response re the looping mistake and Athanasius' note on regular expressions.

    ++ to all.

      The OPs code already implements a solution by cutting of at the beginning and the end of the array, so we can safely imply his desired spec!