Highlight output

A previous posting explained how to use colors on the bash prompt. Here is a convenient filter function to highlight words (or regex's) in files or in the output of commands.

# highlight words in output.
# use: cat /etc/passwd | hl root user
# from: http://chneukirchen.org/blog/archive/2013/07/summer-of-scripts-hl.html 
# zsh: -e${^*} expands $*="a b c" to -ea -eb -ec
# ported to bash by me using xargs
function hl () { 
    if [[ $1 = '-i' ]]; then
    egrep $ARGS --color=always -e '' $(echo $* | xargs -n1 printf "-e%s "); 

I have this in my .bash_profile.

The function first checks, if the first parameter is -i to activate an according parameter to egrep. (If that param was found, shift removes it.) The main work is done by egrep. The parameter --color=always activates output coloring even if it is used in a pipe (or the output is written to a file). This is required to get colors forwarded to less or further processing.

In the original by Ch Neukirchen, the zsh can magically prepend parameters with a string. This was ported to bash by using a combination of xargs and printf. Effectively, egrep gets multiple expressions: The empty string results in all lines being printed (not only the lines with a matching). But since the expression is empty, it matches but does not color anything. Then, the arguments of the hl function are listed, each one prepended with -e.

hl root user


egrep --color=always -e '' -e root -e user


As shown in the comments, this filter can be included in command pipes in the interactive command line:

$ cat /etc/passwd | hl root user

This will highlight the words 'root' and 'user' in the output. To highlight an entire line, use a regex:

$ cat /etc/passwd | hl '.*root.*'

Change color

Multiple instances of hl can be piped together. Since the coloring is done by egrep, that utility can be instructed to use different colors. In a Makefile for a LaTeX project, I have included the following:

check : $(MAIN).pdf
    cat $(MAIN).log \
      | GREP_COLORS='mt=01;33' egrep --color=always --ignore-case -e ''""'' -e'^.*float specifier changed to.*$$' \
      | GREP_COLORS='mt=01;34' egrep --color=always --ignore-case -e ''""'' -e'^.*underful.*$$' \
      | GREP_COLORS='mt=01;32' egrep --color=always --ignore-case -e ''""'' -e'^.*overful.*$$' \
      | GREP_COLORS='mt=01;31' egrep --color=always --ignore-case -e ''""'' -e'^.*warning.*$$' \
      | less

The environment variable GREP_COLORS is set differently for the various instances of egrep. The cluster of quote signs ''""'' is required for the Makefile processing so that the same '' as in the function above remains active (the others are eaten by make and its subshell).

With --color=always, the matching lines are colored and forwarded to the next filter. Finally, a colorful output is presented in less.

The color codes are the same as in the first table of the color introduction.