Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: How to print the lines immediately above and below a matching line?

by Kenosis (Priest)
on Nov 25, 2012 at 18:37 UTC ( #1005513=note: print w/ replies, xml ) Need Help??


in reply to How to print the lines immediately above and below a matching line?

You mention wanting to print the lines above and below a matching line, but your code prints the matching line, too. In case you wanted to print all (two or) three lines, consider the following that you can adapt for files:

use strict; use warnings; my ( $prevLine, $nextLine ); for ( ; ; ) { last if eof DATA; chomp( my $currLine = defined $nextLine ? $nextLine : <DATA> ); if ( $currLine =~ /match this/ ) { print '-' x 25, "\n"; chomp( $nextLine = <DATA> ) if !eof DATA; print $prevLine, "\n" if defined $prevLine; print $currLine, "\n"; print $nextLine, "\n" if defined $nextLine; print '-' x 25, "\n"; } else { undef $nextLine; } $prevLine = $currLine; } __DATA__ The first line match this Not this abcdefg The one above Another match this 1 Another match this 2 the one below match this 2 zxcvbnn Another match this blank above Second to the last line The last line match this

Output:

------------------------- The first line match this Not this ------------------------- ------------------------- The one above Another match this 1 Another match this 2 ------------------------- ------------------------- Another match this 1 Another match this 2 the one below match this 2 ------------------------- ------------------------- Another match this 2 the one below match this 2 zxcvbnn ------------------------- ------------------------- Another match this blank above Second to the last line ------------------------- ------------------------- Second to the last line The last line match this -------------------------

The dashes are printed to show the desired output. If the first or last line is a match, only two lines are printed. If you only want the lines above and below a matching line, delete print $currLine, "\n";.

Hope this helps!

Addition: If you want to avoid printing the same line more than once--like in the example above--and have output that more closely resembles grepping the file, you can do the following:

use strict; use warnings; my ( $prevLine, $nextLine, %printed ); for ( ; ; ) { last if eof DATA; chomp( my $currLine = defined $nextLine ? $nextLine : <DATA> ); if ( $currLine =~ /match this/ ) { chomp( $nextLine = <DATA> ) if !eof DATA; print $prevLine, "\n" if defined $prevLine and !$printed{$prev +Line}++; print $currLine, "\n" if !$printed{$currLine}++; print $nextLine, "\n" if defined $nextLine and !$printed{$next +Line}++; } else { undef $nextLine; } $prevLine = $currLine; } __DATA__ The first line match this Not this abcdefg The one above Another match this 1 Another match this 2 the one below match this 2 zxcvbnn Another match this blank above Second to the last line The last line match this

Output:

The first line match this Not this The one above Another match this 1 Another match this 2 the one below match this 2 zxcvbnn Another match this blank above Second to the last line The last line match this

This uses a hash to keep track of previously printed lines, so they're shown only once.


Comment on Re: How to print the lines immediately above and below a matching line?
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1005513]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2014-07-13 19:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (251 votes), past polls