<?xml version="1.0" standalone="no"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<article id="hilite">
<articleinfo>
  <title>A Regular Expression to Colorize Standard Output on the Command Line</title>
  <author>
    <firstname>Michael</firstname>
    <surname>McDonnell</surname>
    <affiliation>
      <orgname>Winterstorm Solutions, Inc.</orgname>
    </affiliation>
  </author>
  <pubdate>
    <date>2003-09-27</date>    
  </pubdate>
  <copyright>
    <year>1999</year>
    <holder>Michael McDonnell and Winterstorm Solutions, Inc.</holder>
  </copyright>
  <legalnotice>
    <para>This document may be redistributed under the terms of <ulink url="http://www.gnu.org/copyleft/fdl.html">the GNU Free Documentation License</ulink>.</para>
  </legalnotice>
  <abstract>
    <para>A regular expression is describe that can be used to insert ANSI color codes, thereby colorizing text.  A method for using this regular expression on the UNIX command line is given.</para>
  </abstract>
</articleinfo>

<note id="bugfix">
<title>Update</title>
<para>On October 7, 2002 Sergey Goldgaber provided a patch for the <application>hilite</application> script that hacks it to work correctly with regular expressions.  The patch has been incoporated below.  Thanks Sergey!</para>
</note>

<note id="alternative">
<title>A Better Alternative</title>
<para>Shortly after I wrote these instructions on how to colorize output, <ulink url="mailto:pt98jan@student.hk-r.se">Joakim Andersson</ulink> wrote <ulink url="http://www.student.hk-r.se/%7Ept98jan/colortail.html"><application>Colortail</application></ulink> which is a version of the tail program that can colorize its output.  There are few situations where you might want to use the technique described in this document but for most situations you probably will find <ulink url="http://www.student.hk-r.se/%7Ept98jan/colortail.html"><application>Colortail</application></ulink> more useful.  The URL for the home page of <application>Colortail</application>
is <ulink url="http://www.student.hk-r.se/%7Ept98jan/colortail.html">http://www.student.hk-r.se/~pt98jan/colortail.html</ulink>.</para>
</note>

<section id="introduction">
<title>Introduction</title>
<para>As a Systems Administrator and a CGI developer I often find my self watching
active logfiles as they grow.  For instance while debugging a CGI
script I often use the 'tail -f' command to view new error messages generated
by the web server as I test my work.</para>
<para>For a long time I've wanted some way to colorize the output to highlight
certain keywords that I'm interested in the output.  This can be really
helpful if your watching for attempts by crackers to break into your system
(something that I've had to do on a number of occasions unDfortunately).
I'm sure this could be handy in many circumstances. For instance:
<orderedlist>

<listitem>Examining large amounts of data for particular oddities</listitem>

<listitem>Achieving a more aesthetic display for the output of syslogd to a virtual
console or terminal</listitem>

<listitem>Anything that requires the 'grep' command</listitem>

<listitem>Colorize the output of various shell commands for emphasis</listitem>
</orderedlist>
</para>
<para>Recently I decided to solve this problem and it turns out to be a very
simple thing to do.  Here is what you will need:

<orderedlist>
<listitem>An ANSI compatible shell/console/xterm/termcap so you can display color</listitem>

<listitem><application>PERL</application> installed on your system. If you know how to do this with <application>GNU sed</application> please let me know.</listitem>
</orderedlist>
</para>
<para>If your using <application>color-xterm</application>, the linux console, <application>rxvt</application>, <application>kvt</application>, or have the UNIX
environment variable TERM set to <quote>ansi</quote> or <quote>xterm</quote> you should be fine.
Give one of the examples below a try and see if it works. If it doesn't
then see if you can get <application>color-ls</application> to work in your environment (or any other
command listitemne tool that uses color). The same technique shown here
could be used to bold or highlight or underline fonts for use on monochrome
terminals too.</para>
</section>

<section id="example">
<title>A Simple Example</title>
<para>I'm sure that most readers just want to see the example so they can go
and do this in their own context.  This command will accept
any text as standard input and return the same text as output but with
any instance of the word 'GET' turned red.

<blockquote><command>perl -p -e 's/GET/\e[31mGET\e[0m/'</command></blockquote>
</para>
<para>For instance the simplest case would be this:

<blockquote><command>echo "GET" | perl -p -e 's/GET/\e[31mGET\e[0m/'</command></blockquote>
</para>
<para>This example would product a red word <quote>GET</quote>
as output.</para>
<para>Here is another example.  This one will will colorize the output
of the web server logs.  As the logfile grows new listitemnes will be displayed
to the screen.  Any instance of the word <quote>GET</quote> will be turned yellow
and any instance of the word <quote>PUT</quote> will be turned red and cause the bell
to sound.
</para>
<para>
  
<blockquote><command>tail -f /var/log/httpd/access_log | perl -p -e 's/GET/\e[33mGET\e[0m/; s/PUT/\007\e[31mPUT\e[0m/'</command></blockquote>
</para>

<para>For one final example I will show how this trick can be used to colorize
the output of grep.  This will find any listitemne in <filename>/var/log/maillog</filename> that
contains the word <quote>fred</quote> and print those listitemnes after turned instances of
the u can use to colorize standard input!
I named the script <command>hilite</command> on my system.
</para>
<programlisting>
#!/usr/bin/perl
### Usage: hilite &lt;ansi_command> %lt;target_string>
### Purpose: Will read text from standard input and perform specified highlighting
### command before displaying text to standard output.
### License: GNU GPL

$|=1; # don't buffer i/o
$command = "$ARGV0";
$target = "$ARGV1";
$color = "\e[" . $command . "m";
$end = "\e[0m";

while(&lt;STDIN>) {
  s/($target)/$color$1$end/;
  print $_;
}
</programlisting>
</section>
</article>

