Ahoy!
Here is a solution in Perl. Because the lines are before the match, you will have to use a buffer. I included a $bufferSize command line argument. An array named @buffer will always have the last $bufferSize lines. When you find a match, print the buffer which contains the matching line at the end. Here is the code. I ran this on a text file of Programming Perl by Larry Wall.
#!/usr/bin/perl -w
=begin
#usage perl thisFile.pl bufferSize inputFile
#print n lines before match. Because it is BEFORE the match, you will
need to use a buffer. I have limited the buffer to just the given
bufferSize, but you could store the entire file in a buffer if need be.
=end
=cut
my $bufferSize = shift; #grab buffer size from command line arguments
my @buffer;
while(<>){
push(@buffer, "$_"); #store current line in buffer to be accessed when a match is found
if($#buffer > $bufferSize){ shift(@buffer); } #if the buffer is bigger than $bufferSize, remove a line from the beginning of the array with shift, pop removes from the end of the array
if(/diamond/i){ #match found, print buffer
print "\n\n***Match Found: Line $.***\n";
my $i=1;
for(@buffer){print "$i\t: $_"; $i++;}
}
}
Output looks like this
$ perl print.n.lines.before.match.pl 15 programming.perl.txt
***Match Found: Line 25975***
1 : stalled on the target system. (It might need some shared libraries, though, if you
2 : didn’t link everything statically.) However, this program isn’t really any different
3 : than the regular Perl interpreter that runs your script. It’s just precompiled into
4 : a standalone executable image.
5 : The B::CC module, however, tries to do more than that. The beginning of the C
6 : source file it generates looks pretty much like what B::C produced5 but, eventu-
7 : ally, any similarity ends. In the B::C code, you have a big opcode table in C that’s
8 : manipulated just as the interpreter would do on its own, whereas the C code
9 : generated by B::CC is laid out in the order corresponding to the runtime flow of
10 : your program. It even has a C function corresponding to each function in your
11 : program. Some amount of optimization based on variable types is done; a few
12 : benchmarks can run twice as fast as in the standard interpreter. This is the most
13 : ambitious of the current code generators, the one that holds the greatest promise
14 : for the future. By no coincidence, it is also the least stable of the three.
15 : Computer science students looking for graduate thesis projects need look no fur-
16 : ther. There are plenty of diamonds in the rough waiting to be polished off here.
Here is a solution to find n lines AFTER a match from a similar question here.
print specific number of lines after matching pattern
Its almost exactly the same but doesnt require a buffer since the lines are AFTER the match.
#!/usr/bin/perl -w
#usage perl thisFile.pl bufferSize inputFile
#print n lines after match
$n = shift;
while(<>){
if( /diamond/i ){
print "\n\n***Match found: Line $.***\n$_"; #print header and matching line
#print next 81 lines
for( 1 .. $n ){
print "$_:\t" . <>;
}
}
}
Output looks like this
$ perl print.n.lines.after.match.pl 15 programming.perl.txt
***Match found: Line 25975***
0: ther. There are plenty of diamonds in the rough waiting to be polished off here.
1:
2:
3: Code Development Tools
4: The O module has many interesting Modi Operandi beyond feeding the exasper-
5: atingly experimental code generators. By providing relatively painless access to
6: the Perl compiler’s output, this module makes it easy to build other tools that
7: need to know everything about a Perl program.
8: The B::Lint module is named after lint(1), the C program verifier. It inspects
9: programs for questionable constructs that often trip up beginners but don’t nor-
10: mally trigger warnings. Call the module directly:
11: % perl –MO=Lint,all myprog
12:
13:
14:
15:
Good Luck!