Xref: feenix.metronet.com comp.unix.questions:11476
Newsgroups: comp.unix.questions
Path: feenix.metronet.com!news.utdallas.edu!wupost!howland.reston.ans.net!pipex!uunet!boulder!wraeththu.cs.colorado.edu!tchrist
From: Tom Christiansen <[email protected]>
Subject: Re: grep with highlight capability anyone?
Message-ID: <[email protected]>
Originator: [email protected]
Sender: [email protected] (USENET News System)
Reply-To: [email protected] (Tom Christiansen)
Organization: University of Colorado, Boulder
References: <[email protected]>
Date: Thu, 30 Sep 1993 04:21:37 GMT
Lines: 148

From the keyboard of [email protected] (Gary Fong RD):
:UNIXians,
:Does there exist a command as powerful as grep which
:highlights/reversevideo/bolds the matching string/expression?

I use the -H flag in the following program.  Usages
Perl regexps, meaning more like egrep than grep.
See the usage for other features, like recursion,
match-once, textfile only, and paragraph mode.

--tom

#!/usr/bin/perl
#
# tcgrep: tom christiansen's rewrite of grep
# [email protected]
# see usage for features
# yet to implement: -f

require 'getopts.pl';
&Getopts("inqclse:f:xwhv1pHtr") || &usage;

die "-f unsupported" if $opt_f;

$Pattern = $opt_e || shift || &usage;

eval { /$Pattern/, 1 } || die "$0: bad pattern: $@";

if ($opt_H) {
   $ospeed = 13;  # bogus but shouldn't hurt; means 9600
   require 'termcap.pl';
   &Tgetent($ENV{TERM} || 'vt100');
}

$opt_i && $Pattern =~ s/\w/[\u$&\l$&]/gi;
$opt_p && ($/ = '');
$opt_w && ($Pattern = '\b' . $Pattern . '\b');
$opt_x && ($Pattern = "^$Pattern\$");
$opt_1 += $opt_l;
$mult = 1 if ($opt_r || @ARGV > 1) && !$opt_h;

@ARGV = ($opt_r ? '.' : '-') unless @ARGV;

$Errors = $Total = 0;

&match(@ARGV);
print $Total, "\n" if $opt_c;

exit(2) if $Errors;
exit(0) if $Total;
exit(1);

######################################

sub match {
   local($_,$file);
   local(@list);
   local($matches);

   #warn "match /$Pattern/ @_\n";

FILE:
   while ($file = shift) {

       if (-d $file) {
           next FILE if -l $file;
           if (!$opt_r) {
               warn "$0: $file is a directory, but no -r given\n";
               next FILE;
           }
           if (!opendir(DIR, $file)) {
               unless ($opt_q) {
                   warn "$0: can't opendir $file: $!\n";
                   $Errors++;
               }
               next FILE;
           }
           @list = ();
           for (sort readdir(DIR)) {
               push(@list, "$file/$_") unless /^\.{1,2}$/;
           }
           closedir(DIR);
           &match(@list);
           next FILE;
       }

       #warn "checking $file\n";
       if (!open(FILE, $file)) {
           unless ($opt_q) {
               warn "$0: $file: $!\n";
               $Errors++;
           }
           next FILE;
       }

       if ($_ ne '-') {
           next FILE unless -f FILE || $opt_d;
           next FILE unless -T FILE || $opt_b;
       } else {
           warn "$0: reading from stdin\n" if -t STDIN;
       }
       $matches = 0;
LINE:
       while (<FILE>) {
           $matches = 0;
           if ($opt_H) {
               $matches = s/$Pattern/$TC{'so'}$&$TC{'se'}/go;
           } elsif ($opt_v) {
               $matches = !/$Pattern/o;
           } else {
               $matches++ while /$Pattern/go;
           }
           next LINE unless $matches;
           $Total += $matches;
           print "$FILE\n", next FILE if $opt_l;
           print $mult && "$file: ", $opt_n && "$.:", $_ unless $opt_s;
           next FILE if $opt_1;
       }
   }
}

sub usage {
   die <<EOF
usage: $0 [flags] [files]
   i   case insensitive
   n   number lines
   c   give count of matches
   w   word boundaries only
   s   silent mode
   x   exact matches only
   v   invert search sense (lines that DON'T match)
   h   hide filenames
   e   expression (for exprs beginning with -)
   f   file with expressions [unimplemented]
   l   list filenames matching
   1   1 match per file
   r   recursive on directories or dot if none
   p   paragraph mode (default: line mode)
   b   binary files also (default: text only)
   d   device and special files also (default: files only)
   q   quiet about failed file and dir opens
   H   highlight matches
EOF
}
--
   Tom Christiansen      [email protected]
                   Consultant
       Boulder Colorado  303-444-3212