Article 3142 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:3142
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!wupost!howland.reston.ans.net!ux1.cso.uiuc.edu!moe.ksu.ksu.edu!crcnis1.unl.edu!news.unomaha.edu!cwis!mfuhr
From: mfuhr@cwis.unomaha.edu (Michael Fuhr)
Subject: [SOURCE] hlgrep - A highlighting grep
Message-ID: <mfuhr.739072013@cwis>
Sender: news@news.unomaha.edu (UNO Network News Server)
Organization: University of Nebraska at Omaha
Date: Thu, 3 Jun 1993 01:46:53 GMT
Lines: 295

hlgrep is a perl script that works like grep(1), but highlights the
patterns it finds.  Unlike hgrep(1), hlgrep can highlight patterns with
metacharacters.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	README
#	Makefile
#	hlgrep
#	hlgrep.man
#
echo x - README
sed 's/^X//' >README << 'END-of-README'
Xhlgrep README - 2 Jun 93
X
XDESCRIPTION
X===========
X
Xhlgrep is a perl script that works like grep(1), but highlights the
Xpatterns it finds.  Unlike hgrep(1), hlgrep can highlight patterns with
Xmetacharacters.
X
XHighlighting is done using your terminal's standout capability, but you
Xcan edit hlgrep to use any capability you want.  The current version is
Xhardcoded for the vt100, but you can edit it to use tput(1) to get the
Xcapabilities for any terminal at runtime.
X
X
XINSTALLATION
X============
X
X1.  Edit Makefile if you want to change the default installation
X    directories (/usr/local/bin and /usr/local/man/man1).
X
X2.  Edit hlgrep if you want to add tput capability or use terminal
X    capabilities other than vt100 standout.  Comments will tell you
X    how.
X
X3.  Run "make install".
X
X
XMichael Fuhr
Xmfuhr@cwis.unomaha.edu (but probably not after Summer '93).
END-of-README
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
X#------------------------------------------------------------------------------
X# Makefile for hlgrep
X#
X# Configuration:
X#
X#	Change BINDIR to the destination directory for the executable.
X#	Change MANTOP to the top-level manual directory.
X#	Change MANEXT to the manual section.
X#------------------------------------------------------------------------------
X
XBINDIR	= /usr/local/bin
X
XMANTOP	= /usr/local/man
XMANEXT	= 1
X
X#------------------------------------------------------------------------------
X# Shouldn't need to change anything below here.
X#------------------------------------------------------------------------------
X
XHLGREP		= hlgrep
XMANPAGE		= $(HLGREP).man
XMAKEFILE	= Makefile
XREADME		= README
X
XALLFILES	= $(README) $(MAKEFILE) $(HLGREP) $(MANPAGE)
X
XSHARFILE	= $(HLGREP).shar
X
XMANDIR		= $(MANTOP)/man$(MANEXT)
XMANDEST		= $(MANDIR)/$(HLGREP).$(MANEXT)
X
X#------------------------------------------------------------------------------
X# Targets
X#------------------------------------------------------------------------------
X
Xall: $(ALLFILES)
X
Xinstall:
X	install -c -m 755 $(HLGREP) $(BINDIR)
X	install -c -m 644 $(MANPAGE) $(MANDEST)
X
Xshar: $(SHARFILE)
X
X$(SHARFILE): $(ALLFILES)
X	rm -f $(SHARFILE)
X	shar $(ALLFILES) > $(SHARFILE)
X
Xclean:
X	rm -f $(SHARFILE)
END-of-Makefile
echo x - hlgrep
sed 's/^X//' >hlgrep << 'END-of-hlgrep'
X#!/usr/bin/perl
Xeval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
X	if 0;
X#------------------------------------------------------------------------------
X# hlgrep - highlight grep
X#
X# See the manpage for more information.
X#------------------------------------------------------------------------------
X
Xrequire "getopts.pl";
X
X($progname = $0) =~ s#.*/##;
X
X#------------------------------------------------------------------------------
X# Define the begin/end standout codes for the terminal.  The hardcoded
X# values are for the vt100 and its kind.  For other terminals, look up
X# the so/se capabilities in /etc/termcap or the smso/rmso capabilities
X# in the terminfo database.  A more robust way would be to get the codes
X# at runtime with something like
X#
X#	$so = `tput smso`;
X#	$se = `tput rmso`;
X#
X# if your system has tput.  The disadvantage of this is the cost of
X# running the two tput processes.  An even better way would be to read
X# the values directly from /etc/termcap or the terminfo database.
X#
X# Feel free to any terminal capability for highlighting.  Here are a few
X# capabilities for the vt100 (some may not work on your terminal):
X#
X#	Name		Termcap/Terminfo	String
X#	---------	----------------	------
X#	Standout	     so/smso		\e[7m
X#	Underline	     us/smul		\e[4m
X#	Bold		     md/bold		\e[1m
X#	Blinking	     mb/blink		\e[5m
X#------------------------------------------------------------------------------
X
X$so = "\e[7m";
X$se = "\e[m";
X
X#------------------------------------------------------------------------------
X# Get options and pattern from command line.  Check syntax.
X#------------------------------------------------------------------------------
X
X&Getopts("aDhinw") || exit 2;
X$pattern = shift @ARGV;
X
Xdo { $! = 2; die "Usage: $progname [ -aDhinw ] pattern [ filename ... ]\n" }
X	unless ($pattern);
X
X#------------------------------------------------------------------------------
X# Escape any slashes in the pattern, because we use the slash as the
X# pattern-matching delimiter.
X#------------------------------------------------------------------------------
X
X$pattern =~ s#/#\\/#;
X
X#------------------------------------------------------------------------------
X# Set some variables to be used when building the command to be eval'd.
X#------------------------------------------------------------------------------
X
X$opt_a || do { $maybe_skip = "next"; };
X$opt_h || do { $name = "\$ARGV:" if (@ARGV > 1); };
X$opt_i && do { $sflags = "i"; };
X$opt_n && do { $linenum = "\$.:"; };
X$opt_w && do { $pattern = "\\b($pattern)\\b"; };
X
X#------------------------------------------------------------------------------
X# Generate the code.  Explicitly closing each file will reset the line
X# number ($.) (see eof in the perl manpage).
X#------------------------------------------------------------------------------
X
X$cmd = <<"AMEN";
X\$exit_status = 1;
Xwhile (<>) {
X	if (s/$pattern/$so\$&$se/g$sflags) {
X		\$exit_status = 0;
X	}
X	else {
X		$maybe_skip;
X	}
X	print "$name$linenum\$_";
X} continue {
X	close ARGV if eof;
X}
Xexit \$exit_status;
XAMEN
X
X#------------------------------------------------------------------------------
X# Execute the code.  But print it first if the user wanted.
X#------------------------------------------------------------------------------
X
Xprint STDERR $cmd if $opt_D;
X$| = 1;
Xeval $cmd;
END-of-hlgrep
echo x - hlgrep.man
sed 's/^X//' >hlgrep.man << 'END-of-hlgrep.man'
X.TH HLGREP 1 "2 Jun 1993"
X.SH NAME
Xhlgrep - highlight grep
X.SH SYNOPSIS
Xhlgrep [ -aDhinw ]
X.I pattern
X[
X.IR filename " .\|.\|. ]"
X.SH DESCRIPTION
X.B hlgrep
Xsearches the given
X.I filenames
X(or the standard input if no files are specified)
Xfor lines containing the regular expression
X.IR pattern 
Xand prints those lines with the matching patterns highlighted.
X.LP
XRegular expressions are the same as those used in
X.BR perl (1).
X.SH OPTIONS
X.TP
X.B \-a
XPrint all lines, not just those that contain matching patterns.
XThis is useful for seeing the patterns in context.
X.TP
X.B \-D
XPrint debugging info.
X.B hlgrep
Xbuilds a command for perl to
X.IR eval .
XThis option causes that command to be printed to standard error before
Xany processing.
X.TP
X.B \-h
XDon't print filenames when more than one file is given on the command line.
X.TP
X.B \-i
XIgnore case.
X.TP
X.B \-n
XPrint line numbers.
X.TP
X.B \-w
XMatch patterns only as complete words.
X.LP
XTypical grep options like
X.B \-l
X(print filenames only),
X.B \-c
X(print count of matching lines only),
X.B \-s
X(set exit status only), and
X.B \-v
X(print lines that don't match) defeat the purpose of this program
X(highlighting) and aren't provided.  Use one of the other greps if
Xyou need them.
X.SH NOTES
X.B hlgrep
Xis written in perl, so your system must have perl installed.  It uses
Xthe package
X.BR getopts.pl ,
Xwhich some versions of perl earlier than 4.036 don't have.
X.SH "SEE ALSO"
X.BR agrep (1),
X.BR egrep (1),
X.BR fgrep (1),
X.BR grep (1),
X.BR hgrep (1),
X.BR perl (1),
X.BR tput (1)
X.SH BUGS
XThe current version of
X.B hlgrep
Xuses hardcoded values for terminal capability strings, but it can
Xbe configured to use
X.BR tput (1)
Xto get terminal capabilities at runtime.
X.LP
XPlease report any other bugs to the author.
X.SH DIAGNOSTICS
XExit status 0 if pattern found, 1 if pattern not found, 2 if syntax
Xerror.
X.SH AUTHOR
XMichael Fuhr (mfuhr@cwis.unomaha.edu, but probably not after
XSummer '93).
END-of-hlgrep.man
exit

--
Michael Fuhr                           "What is the sound of Perl?  Is it not
mfuhr@cwis.unomaha.edu                  the sound of a wall that people have
                                        stopped banging their heads against?"
                                                                 - Larry Wall