Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: how to check for a word in a file and if found remove that line, the above line and the below line from the file.

by mr_mischief (Monsignor)
on Jan 20, 2016 at 18:35 UTC ( #1153196=note: print w/replies, xml ) Need Help??


in reply to how to check for a word in a file and if found remove that line, the above line and the below line from the file.

You need to figure out if you're worried about overlapping matches, and specify your problem accordingly. There are solutions which will check excluded lines to see if there are additional lines to exclude after those. There are also solutions that will exclude a set of lines and move on as if the excluded lines after (but not before of course) the matched line can't possibly match. Here's an example of the difference.:

print me exclude me match me match me exclude me print me

vs:

print me exclude me match me would match me but the above line excluded me print me anyway because the previous line wasn't matched after exclusi +on print me

Here's a filter that will do either, based on a command-line argument. It also is configurable for how many additional lines to exclude (before, after, or both).:

#!/usr/bin/perl use strict; use warnings; use Getopt::Long (); process( init() ); exit; sub process { my $opts = shift; my @buffer = (); my $wait = 0; while ( <> ) { if ( ( scalar @buffer ) > $opts->{ 'b' } ) { print ( shift @buffer ); } if ( $wait ) { $wait--; next unless $opts->{ 'nest' }; } else { push @buffer, $_; } if ( /$opts->{ 'pattern' }/ ) { @buffer = (); $wait = $opts->{ 'a' }; } } print @buffer; } sub init { my %options = ( 'help' => 0, 'a' => 1, 'b' => 1, 'c' => 0, 'nest' => 0, 'pattern' => '', ); Getopt::Long::Configure( 'gnu_getopt' ); Getopt::Long::GetOptions( \%options, 'help+', 'a=i', 'b=i', 'c=i', + 'nest+', 'pattern=s' ); if ( $options{ 'c' } ) { $options{ 'a' } = $options{ 'b' } = $options{ 'c' }; } if ( $options{ 'help' } ) { warn "Usage: $0 [[--help]|[[-a <n>] [-b <n>]|[-c <n>]] [--nest +] --pattern <s>\n\n" . "Print the input file excluding the matched line provided by + the -p argument and as many lines before and after that line as spec +ified.\n\n" . "\t--help\t\t\tthis help message\n" . "\t-a <number>\t\texclude <number> lines after the matched l +ine\n" . "\t-b <number>\t\texclude <number> lines before the matched +line\n" . "\t-c <number>\t\texclude <number> lines before and after th +e matched line, overriding -a and -b in the process\n" . "\t--nest\t\t\tmatch lines already excluded by a preceding m +atch, and exclude the following lines accordingly\n" . "\t--pattern <string>\texclude the line matching this patter +n (may be a regular expression) and other lines as specified by the o +ther options\n\n"; exit 0; } return \%options; }

I made it a filter as the file handling itself is kind of secondary to the problem at hand. It's possible to add input and output arguments either positionally or via flags. My preference if I were to flesh it out a bit more would be to default to STDIN and STDOUT but allow flags to override one, the other, or both.

  • Comment on Re: how to check for a word in a file and if found remove that line, the above line and the below line from the file.
  • Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1153196]
help
Chatterbox?
and monks are getting baked in the sun...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2018-02-18 05:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When it is dark outside I am happiest to see ...














    Results (250 votes). Check out past polls.

    Notices?