Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Print n lines after a matched line

by sreek3502 (Novice)
on Jun 13, 2018 at 18:14 UTC ( #1216577=perlquestion: print w/replies, xml ) Need Help??
sreek3502 has asked for the wisdom of the Perl Monks concerning the following question:

I have an input file having following contents

SCHEDULE "TEST"

DESCRIPTION "Do Some stuff"

MINUTE "53"

HOUR "21"

SCHEDULE "DUMMY CHECK"

DESCRIPTION "Do some stuff"

Check something

INTERVAL "10m"

MINUTE "50"

HOUR "21"

I need to match the 3rd line after the matched line SCHEDULE "DUMMY CHECK" which is INTERVAL "10m". I have written the below code for that purpose, however i'm not sure if this is the exact way of doing it, or do we have any simple other logics.

use strict; use warnings; my $file = "input.txt"; my @data; open (IN,"<","$file"); my $count = 0; while (<IN>) { $count = 1 if /SCHEDULE\s"(DUMMY\sCHECK)".*/; if ($count >= 1 and $count <= 6) { @data = $_; print @data; $count++; } }

Replies are listed 'Best First'.
Re: Print n lines after a matched line
by Discipulus (Monsignor) on Jun 13, 2018 at 18:36 UTC
    Hello sreek3502,

    If your input is somehow fixed in it's content the easiest thing is using the flip-flop operator (see flip flop at my library and in perlop):

    while (<DATA>){ print if /SCHEDULE "DUMMY CHECK"/ .. /INTERVAL/; }

    If you just want to print 3 lines after a match (but notice you have empty lines that count! i used 6 lines..) you can use or a count, as you already have done, or use the special variable $. (explained in perlvar ) that is line number:

    my $switch; while (<DATA>){ $switch = $. if /SCHEDULE "DUMMY CHECK"/; if ( $switch and $. <= $switch + 6){ print; } }

    As final note @data = $_; does not make muche sense for me: you want to split the line? dont forget also to chomp

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Print n lines after a matched line
by shmem (Chancellor) on Jun 14, 2018 at 12:39 UTC

    Discipulus solution above is very elegant. Here's the correction of the error in your script:

    use strict; use warnings; my $file = "input.txt"; my @data; open (IN,"<","$file"); my $count = 0; while (<IN>) { $count = 1 if /SCHEDULE\s"(DUMMY\sCHECK)".*/; if ($count >= 1 and $count <= 6) { - @data = $_; - print @data; + $_ = <IN>; + print; $count++; } }

    You did not read the next line off your input file descriptor.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Print n lines after a matched line
by haukex (Canon) on Jun 13, 2018 at 18:44 UTC

    Crossposted to StackOverflow. Crossposting is acceptable, but it is considered polite to inform about it, so that efforts are not duplicated.

Re: Print n lines after a matched line
by LanX (Bishop) on Jun 14, 2018 at 17:06 UTC
Re: Print n lines after a matched line
by Marshall (Abbot) on Jun 14, 2018 at 17:08 UTC
    I like the flip-flop operator as demo'd by Discipulus. If I don't use that, I often use the following pattern. The flip-flop operator maintains the state of whether you are inside the record or not - that's a very nice feature. Anyway, without the flip-flop, instead of maintaining a flag to tell me if I'm in the record or not, I call a subroutine to keep track of the "state". This may be a bit "wordy", but the logic is crystal clear (at least to me).
    #!/usr/bin/perl use strict; use warnings; while (defined (my $line = <DATA>)) { process_record($line) if $line =~ /^\s*SCHEDULE "DUMMY CHECK"/; } sub process_record { my $line = shift; #the "trigger line" print $line; for (1..3) #maybe have regex for "end of record"? { my $line = <DATA>; print $line; } print "\n"; #just a spacer } =prints SCHEDULE "DUMMY CHECK" DESCRIPTION "Do some stuff" Check something INTERVAL "10m" SCHEDULE "DUMMY CHECK" DESCRIPTION "Do some more stuff" Check something INTERVAL "30m" =cut __DATA__ SCHEDULE "TEST" DESCRIPTION "Do Some stuff" MINUTE "53" HOUR "21" SCHEDULE "DUMMY CHECK" DESCRIPTION "Do some stuff" Check something INTERVAL "10m" MINUTE "50" HOUR "21" SCHEDULE "TEST" DESCRIPTION "Do Some stuff" MINUTE "53" HOUR "21" SCHEDULE "DUMMY CHECK" DESCRIPTION "Do some more stuff" Check something INTERVAL "30m" MINUTE "50" HOUR "21"
Re: Print n lines after a matched line
by taint (Chaplain) on Jun 13, 2018 at 22:18 UTC

    It's difficult to know how to best respond, or provide the best answer, without a bit more context. IOW you mention match, which is really a simple matter, as described in the linked Perl documentation -- especially if the given text file is static.

    But, then again. If you need to further process that file, or perhaps another file. The (best) answer might be quite different.

    tl;dr;
    You will need to help us, help you.

    Evil is good, for without it, Good would have no value
    λɐp ʇɑəɹ⅁ ɐ əʌɐɥ puɐ ʻꜱdləɥ ꜱᴉɥʇ ədoH

    A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1216577]
Approved by taint
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2018-09-23 19:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Eventually, "covfefe" will come to mean:













    Results (191 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!