Using color to highlight in a terminal window

Posted: November 17, 2011 in solaris, tech

Unix systems have some great command line tools: Find, grep, cut, split, tr, sed, awk — all amazing tools.
But sometimes I still can’t quickly see what I need to see in a fast scrolling window. The text is the same font and color, and the background never changes. When scrolling through using ‘less’ and using the search option the word can be bolded or in other ways marked– but ‘less’ is not always useful when you are looking at the output of ps, tailing a logfile, top, prstat, snoop, tshark…
Well I finally found something. Cobbled together something is a little closer to the truth.

Sometime back I found a suggestion on using one of my favorites to change color: perl. This hack is pretty easy but involved remembering the very complicated one-liner to type it when needed, or pulling it out of history, or little notes files in my home directory. It uses the color mechanisms within the terminal, so your terminal and shell naturally have to support color.

It would go something like this (where 31 is red and 43 is yellow [I think]): tail system.log |perl -pe ‘s/Throttling/\e[1;31;43m$&\e[0m/ig’

tail system.log | perl -pe 's/Throttling/\e[1;31;43m$&\e[0m/ig'

Perl one-liner typed in command pipeline

It definitely was a start. But it wasn’t easy. I used it for years this way– look at the file or output and realize my eyes are lost. So I would cat my note file in my home directory, run the command again piping it through the perl one-liner to highlight the word I wanted (like “Throttling” in my example).

One day I had a enough. “Kevin, there has to be an easier way,” I said to myself. I messed about with trying ‘alias’ commands to set it up. That was fine for a static word to highlight but it wasn’t possible to stick in a variable to highlight different words when I needed to.

So.. I went back to shell basics and rediscovered “functions”.  By building several shell functions using my original Perl one-liner with color changes and different variable names I can now highlight multiple different words all at the same time:

Functions highlighting multiple words at the same time

Functions highlighting multiple words at the same time

Pretty awesome!

So here’s how it is setup. First, I find some colors that look in my terminal. I use the “Novel” color scheme in my Mac terminal found these three useful color schemes but your could easily have more and change them to match your heart’s desires:

  • Red on Yellow : 31;43m
  • Lt Blue on Dark: 32;44m
  • Lt Blue on purple: 32;45m

Next up is combing them with individual variables and putting them in my .profile so that they are active when I login to a system. I edit my .profile and at the bottom I add these three lines:

  • redy () { command perl -pe “s/$redy/\e[1;31;43m$&\e[0m/ig” ; }
  • blue () { command perl -pe “s/$blue/\e[1;32;44m$&\e[0m/ig” ; }
  • purp () { command perl -pe “s/$purp/\e[1;32;45m$&\e[0m/ig” ; }

The first word is the name of the function. This can be called just like a command or an alias, but it calls the command inside the brackets which is the original Perl one-liner modified with a variable. The variable is not a Perl scalar but is a shell variable that will be replaced with the contents before Perl executes.

Once you’ve edited your .profile you need to exit and re-login or source the .profile into your environment. You can type ‘set’ to see if it is in your environment before attempting to use it.

When the function is built and in your environment you are ready to add it to your pipeline. The pipeline must start off with defining the variable and within the same session execute your command before handing that off to the pipeline. The way to do this is with an “&&” joining construct. It tells the shell “set this and if successful do this” and the pipeline follows so the whole enchilada is fed to the next command. It’s not complicated, just messy to describe. So let me show you:

  • blue=5004 && redy=5007 && purp=5008 && snoop -Vd ce0 port 5007 or port 5008 or port 5004|redy |purp|blue
    • set blue to be the word 5004
    • set redy to be the word 5007
    • set purp to be the word 5008
    • execute snoop command
    • pipe feed output to function redy
    • pipe feed output to function purp
    • pipe feed output to function blue
  • Sip coffee and watch your magic!

    Example Execution of commands

    Example Execution of commands

It is still a fair bit of typing and still requires some biological memory  but it is easier.

I hope this helps someone!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s