in reply to Emulating GNU grep -A and -B switches with perl (was: linux grep feature)

There is already Grep - print matched line and next N lines, and i know there is another one that handles the -B functionality as well as the -A, but i can't find it. Both of these (i think) were written before Tie::File was realeased, here is a version i just slapped together for the fun of it. :) Comments and suggestions are more than welcome.
use strict; use warnings; use Tie::File; use Getopt::Std; our %opts; getopt('AB',\%opts); die "USAGE: $0 [-An] [-Bn] match file" unless @ARGV; my ($match,$filename) = @ARGV; my @file; tie @file, 'Tie::File', $filename; # i wish there was a way for grep to return indices ... my @found; for (0..$#file) { push @found, $_ if $file[$_] =~ /$match/; } for (@found) { my ($start,$end) = ($_,$_); $start -= $opts{A} if $opts{A}; $end += $opts{B} if $opts{B}; $start = 0 if $start < 0; $end = $#file if $end > $#file; print $_,$/ for @file[$start..$end]; }
And yes, Perl is fun! :D

jeffa

L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)

Replies are listed 'Best First'.
Re: (jeffa) Re: linux grep feature
by cees (Curate) on Jun 11, 2003 at 15:47 UTC

    Your code works great for simple cases, but fails for files that have matches that are close together. You end up with duplicate lines being displayed.

    for example try the following:

    grep.pl -A 1 -B 1 test data

    with the file 'data' containing:

    test 1 test 2 test 3

    The results are:

    test 1 test 2 test 1 test 2 test 3 test 2 test 3

    Also your version will parse the entire file before printing out any results. This will be slow for large files.

    Still a good base to start from though...

    Cheers

    Cees