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: 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