A Regular Expression to Colorize Standard Output on the Command Line

by Michael McDonnell on 2003-09-27
Other Formats:

A Regular Expression to Colorize Standard Output on the Command Line

Michael McDonnell

Winterstorm Solutions, Inc.

This document may be redistributed under the terms of the GNU Free Documentation License.

2003-09-27

Abstract

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.


Table of Contents

Introduction
A Simple Example

Update

On October 7, 2002 Sergey Goldgaber provided a patch for the hilite script that hacks it to work correctly with regular expressions. The patch has been incoporated below. Thanks Sergey!

A Better Alternative

Shortly after I wrote these instructions on how to colorize output, Joakim Andersson wrote Colortail 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 Colortail more useful. The URL for the home page of Colortail is http://www.student.hk-r.se/~pt98jan/colortail.html.

Introduction

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.

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:

  1. Examining large amounts of data for particular oddities
  2. Achieving a more aesthetic display for the output of syslogd to a virtual console or terminal
  3. Anything that requires the 'grep' command
  4. Colorize the output of various shell commands for emphasis

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:

  1. An ANSI compatible shell/console/xterm/termcap so you can display color
  2. PERL installed on your system. If you know how to do this with GNU sed please let me know.

If your using color-xterm, the linux console, rxvt, kvt, or have the UNIX environment variable TERM set to “ansi” or “xterm” 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 color-ls 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.

A Simple Example

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.

perl -p -e 's/GET/\e[31mGET\e[0m/'

For instance the simplest case would be this:

echo "GET" | perl -p -e 's/GET/\e[31mGET\e[0m/'

This example would product a red word “GET” as output.

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 “GET” will be turned yellow and any instance of the word “PUT” will be turned red and cause the bell to sound.

tail -f /var/log/httpd/access_log | perl -p -e 's/GET/\e[33mGET\e[0m/; s/PUT/\007\e[31mPUT\e[0m/'

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 /var/log/maillog that contains the word “fred” and print those listitemnes after turned instances of the u can use to colorize standard input! I named the script hilite on my system.

#!/usr/bin/perl
### Usage: hilite <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(<STDIN>) {
  s/($target)/$color$1$end/;
  print $_;
}