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

Hello Perl Monks

Can somebody tell me how to get script to print out say the next few lines after a regex match? Currently I'm able to get the first line matched but nothing below it. My file contains these entries.

#Feb 19 15:22:21 206021 152221.684878 7219 INFO: Update certificate +for user=(XXX) , updated by XXX #Feb 19 15:22:21 206021 152221.694424 7220 INFO: MessageFromClient{m +sgId:UPDATE,state:{lastUpdatedDateTime:1427129443000,id:george,type:T +akerUser,lastUpdatedBy:xxx,partyDBId:TakemeHome,permissions:{perms:[P +rocess,SequesteredTrading],],r:0}}}}

#!/usr/bin/perl -w use strict; my $mesg = ""; #Feb 19 15:22:21 206021 152221.684878 7219 INFO: Update certificate +for user=(XXX) , updated by XXX #Feb 19 15:22:21 206021 152221.694424 7220 INFO: MessageFromClient{m +sgId:UPDATE,state:{lastUpdatedDateTime:1427129443000,id:george,type:T +akerUser,lastUpdatedBy:xxx,partyDBId:TakemeHome,permissions:{perms:[P +rocess,SequesteredTrading],],r:0}}}} my $search = "cat /pathtomydirectoryfiles/`date +%Y/%m/%d`/test/testlo +gs/*"; open FF, "$search |"; while (<FF>) { if (/Update certificate.*/){ #$count = 1 if /Updating certificate.*/; #if ($count >= 1 and $count <=2) { #next if /Updating certificate/; #print; #$count++; $mesg = "$_"; print $mesg; next; } } close FF;

Appreciate the assistance

Replies are listed 'Best First'.
Re: How to print 5 lines below after a regex match
by GotToBTru (Prior) on Feb 24, 2016 at 19:27 UTC

    You test only for matching, but of course what you really want is lines after the match. So while you need to make note that it has matched, you need another indication to tell you when to print. And the indication needs to go away once you've printed the limited number of following lines. '$flag' gets set when we match; '$few' allows us to supply the number of lines, or just allow a default value of 2.

    use strict; my $flag = 0; my $few = shift || 2; while (<DATA>) { print $_ if ($flag-- > 0); $flag = $few if (/Update certificate/); } __DATA__ Useless line before match Feb 19 15:22:21 206021 152221.684878 7219 INFO: Update certificate f +or user=(XXX) , updated by XXX First line after match Second line after match Third line after match Fourth line after match

    Update: output

    H:\perl> perl 1156056.pl First line after match Second line after match H:\perl>perl 1156056.pl 3 First line after match Second line after match Third line after match
    But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

      Thanks I see the lines posted below my match. One last thing which I should have included, how do also print the matched line as well. Many thanks

        Set the flag first then print

        use strict; my $flag = 0; my $few = shift || 3; while (<DATA>) { $flag = $few if (/Update certificate/); print $_ if ($flag-- > 0); }
        poj
Re: How to print 5 lines below after a regex match
by AnomalousMonk (Archbishop) on Feb 25, 2016 at 01:06 UTC

    Here's a pure-regex approach. It needs Perl version 5.10 or higher due to the use of the  \K construct, but that can be worked around if needed.

    c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; my $s = qq{foo\nxyzzy\nline 1\nline 2\nline 3\nline 4\nline 5\nline 6 +\netc.}; print qq{[[$s]]}; ;; my $line = qr{ [^\n]* \n }xms; my $before = qr{ xyzzy \n }xms; my $n = 4; my $match = my ($n_lines) = $s =~ m{ $before \K ((?: $line){$n}) }xm +s; print qq{match: <<$n_lines>>} if $match; " [[foo xyzzy line 1 line 2 line 3 line 4 line 5 line 6 etc.]] match: <<line 1 line 2 line 3 line 4 >>

    Update: Actually, just take the  \K out and this code, as it stands, works just fine under any Perl version!


    Give a man a fish:  <%-{-{-{-<

Re: How to print 5 lines below after a regex match
by FreeBeerReekingMonk (Deacon) on Feb 24, 2016 at 23:32 UTC
    Here is my (perlgolf) oneliner code:

    As we do not have a terminator string, I used undef.
    $M=1 when the match is found,
    $M=2 on the first line after the match.

    perl -ne 'if($M=/Update certificate/..undef){print if($M>1 && $M<=6)}'

    to also print the matched line as well (header):

    perl -ne 'if($M=/Update certificate/..undef){print if $M<=6}'

    IMPORTANT: due to having no terminator string, it will only match once in a given file.