I have two commands in perl and one test file test.txt:

$ cat test.txt
aaa bla
bbb foo
#ccc bar
ddd 444

First perl expression colorizes any occurrence of aaa or bbb with red color:

cat test.txt | perl -pe "s/(aaa|bbb)/\e[1;31m\1\033[0m/g"

Second expression colorizes green any line starting with #:

cat test.txt | perl -pe "s/^(#.*)/\e[0;32m\1\033[0m/g"

Now I need to combine these two expressions into one, having following properties:

if line starts with #, then colorize whole line using green color. If line does not start with # colorize any occurrence of aaa or bbb using red color.

In other words, if line is already green (i.e. typical; comment line), I don't want to color any possible occurrence of aaa or bbb. Otherwise, I want to colorize them red.

How could I combine my two expressions to achieve this ?


The simplest way to do it would be:

cat test.txt | perl -pe "s/^(#.*)/\e[0;32m\1\033[0m/g || s/(aaa|bbb)/\e[1;31m\1\033[0m/g"

This uses the logical or operator || to tell perl to only run the second s/// if the first failed. i.e. similar to an if (/#/) ... else if (/aaa|bbb/) ...

You can add more || s/// at the end of the script if you need to but if you need to search for and colourise many more matches, doing it as a one-liner would become far too complicated. In that case, rewrite the whole thing as a standalone #! /usr/bin/perl -p script, perhaps with one s///g || per line, and a final semi-colon instead of || on the last line.

For example:

#! /usr/bin/perl -p

s/^(#.*)/\e[0;32m\1\033[0m/g ||
s/(aaa|bbb)/\e[1;31m\1\033[0m/g || 
s/(ccc)/\e[1;34m\1\033[0m/g ;

Note that doing it like this means that only one match will ever be found on any given line, and the first match wins. So in my longer script example above, if 'aaa' or 'bbb' are found on a line then they will be colourised but if 'ccc' is on the same line, it won't be.

Finally, it looks like you are re-inventing the wheel. There are several tools that already exist to colourise text. The highlight tool, for example. It's mostly used for syntax highlighting of source code but can be used to colourise any kind of text.

  • BTW, highlight is packaged for debian (and ubuntu, mint, etc) and probably for other linux distros too. – cas Sep 21 '15 at 1:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.