print me
exclude me
match me
match me
exclude me
print me
####
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 exclusion
print me
##
##
#!/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 ] [-b ]|[-c ]] [--nest] --pattern \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 specified.\n\n"
. "\t--help\t\t\tthis help message\n"
. "\t-a \t\texclude lines after the matched line\n"
. "\t-b \t\texclude lines before the matched line\n"
. "\t-c \t\texclude lines before and after the matched line, overriding -a and -b in the process\n"
. "\t--nest\t\t\tmatch lines already excluded by a preceding match, and exclude the following lines accordingly\n"
. "\t--pattern \texclude the line matching this pattern (may be a regular expression) and other lines as specified by the other options\n\n";
exit 0;
}
return \%options;
}