[Techtalk] grep question

Almut Behrens almut_behrens at yahoo.com
Sat Jan 19 00:49:20 EST 2002


On Fri, Jan 18, 2002 at 10:44:27AM -0500, Erin Mulder wrote:
> > Hmm... this server must have an older version installed.  No such
> > option listed in man (and it doesn't work when tried).
> 
> I grabbed a copy of the latest grep, but it turns out there's no c
> compiler on this server (???) and I need root to easily install the gcc 
> binaries I've found (which want to install into /usr/local/).
> 
> So, I guess I'm just going to try a shell script.

A while ago, I was in desperate need of something similar on an
old HPUX system. The existing grep didn't even have proper regex
functionality, not to mention the ability to print context.
But luckily, there was a working perl, so I hacked up a little
quick-'n-dirty script, which you find attached below.
It's neither pretty nor convenient (you have to set the number of
pre/post context lines in the script itself), and it also doesn't wash
your dishes, but for me it did what it was meant to do.  Also, it
shouldn't be too difficult to modify it to your heart's desire...

You'd call it like an ordinary grep

  cgrep regex file(s)

e.g. "cgrep '^sub ' cgrep" to extract all subroutines (+context) from
the script itself.

But it doesn't support any of grep's options like -i (you'd have to
put that behind the regex-match in the script). Line numbering (-n)
is hardcoded, but it's not being reset for individual files, if you
grep several files at once.

Maybe you still find it useful -- in case you haven't written something
yourself in the meantime...

Cheers,
Almut

-------------- next part --------------
#!/usr/bin/perl

my $pre  = 3;   # lines before match
my $post = 10;  # lines after match

my $regex = shift @ARGV;

my @context;
my $bufsize = $pre + $post + 1;
my $currline = $pre;

while (<>) {
    to_context( (/$regex/o ? ">>":"  ") . " $.: $_");
}
for (1..$post) { to_context() }

sub to_context {
    $context[$currline] = shift;
    $currline = nextidx($currline);
    print_context() if substr($context[idx($currline+$pre)],0,1) eq '>';
}

sub print_context {
    print "-----\n";
    my $c=$bufsize;
    for (my $i=idx($currline); $c--; $i=nextidx($i)) {
        print $context[$i];
    }
}

sub idx     { (shift) % $bufsize }
sub nextidx { idx( (shift) + 1 ) }


More information about the Techtalk mailing list