#!/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; }