Polishing the wegrep Wrapper Script

So, that's two down: a smarter divider line and the ability to number the output lines. Let's see how that works:


$ sh wegrep.sh '^Alice' wonderland.txt
-----
12:
13:     ^Alice was beginning to get very tired of sitting by
14:     her sister on the bank, and of having nothing to do:
-----
27:     There was nothing so very remarkable in that; nor did
28:     ^Alice think it so very much out of the way to hear the
29:     Rabbit say to itself, 'Oh dear! Oh dear! I shall be
-----

The dividers work perfectly, showing up the minimum amount needed to denote each matching block of lines clearly, and the line numbers are neat and helpful.

The trickier part is still left to tackle. How do you actually highlight the match in each section?

ANSI Color Sequences

You may not realize it, but odds are incredibly high that your Terminal or xterm window, whether you're directly in a Linux system or connecting via a Windows or Mac computer, is emulating what's known as an ANSI terminal.

ANSI is the American National Standards Institute, but don't be misled; this is a global standard, particularly when it comes to colors, bold and other visual aspects to the terminal.

The problem is, the sequences to turn on and turn off bold or specific colors has to be fairly obscure to ensure that users don't accidentally end up invoking it. So "color:" would be a fail, as would "<color>". Instead, it's done through an escape sequence: Escape + [ + 3 + 2 + m causes all subsequent text to be rendered as green, for example.

The Escape + [ sequence prefix has a name of its own. It's a Control Sequence Introducer, although you probably don't need to know that! You can find a full table of ANSI color sequences on-line.

Once you're done with the highlighted text, you'll need to change the display back to regular text, and that's done with the sequence Escape + [ + 0 + m.

Add them all up, and here's what you use to highlight whatever value is stored as $1 in a string:


\033[32m$1\033[0m

The \033 is a shorthand for Escape. Rather than make this an echo statement, it's a good use of printf, so here's the sequence:


sed ''/$1/s//`printf "\033[32m$1\033[0m"`/'' "$2"

This basically replaces every occurrence of $1 with itself, prefixed with the ANSI green sequence and suffixed with the sequence to return subsequent text to its normal display characteristics.

______________________

Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.