tail -f logfile.log | perl -pe 's/.*foo*/\e[1;41m$&\e[0m/g'    

will color all the lines containing the pattern "foo" in the logfile.log file.

How can I make use of this in order to highlight not the whole line but just the exact pattern?

echo "WARN ERROR foo"|sed 's#WARN#\x1b[33m&#; s#ERROR#\x1b[31m&#; s#foo#\x1b[32m&#'    

I mean if I want to do something like this, how can I manage?

  • I don't understand, why aren't you just using the same regex for sed and perl? – terdon Nov 25 '14 at 13:46
  • what is the content of log file, and what output you expecting?? – Hackaholic Nov 25 '14 at 13:54
  • It's a live log file that is growing every seconds. And the server runs HPUX as OS. The only shell installed on it is ksh. What I need to search is depends but I need to highlight all the "Warning" words in "Green", all the "Error" words in "Red", all the "Bla" words in "Blue" like in the second example I gave but using the structure I used in first example.(I mean perl -pe) If there is any other way to do this highlighting in an old ksh lacking of most of the applications and properties of bash, I am open to all solutions. – ybaylav Nov 25 '14 at 14:08
  • What I need basically to get find out exactly what I search in a log quickly, and read them easily without losing time. And additionally to this, if there's a way get the copy of the logs and shape it in a human readable form It would be superb for me to learn about such a tool. ( I mean the paragraphs, new lines, line spaces, colors etc.) – ybaylav Nov 25 '14 at 14:14

First of all, you can use almost the exact same regular expression and syntax as you did with sed. Just change & to $& for Perl:

echo "WARN ERROR foo" | 
    perl -pe 's#WARN#\x1b[33m$&#; s#ERROR#\x1b[31m$&#; s#foo#\x1b[32m$&#'    

Or, using your original Perl approach, just remove the .* on either side of the pattern you want to match:

tail -f logfile.log | perl -pe 's/foo/\e[1;41m$&\e[0m/g'    

For a more versatile approach, you can use the little script I have posted in my answer here. With it, you can color up to 10 patterns with a different color for each. For example, to color the words ERROR,WARNING and foo, in a different color, case-insensitively:

tail -f logfile.log | color.pl -il "error,warning,foo"
  • I'll try each and everymethodology provided. Just trying to speed up and develop my skills, looking for the cleanest and fastest way to get required information. Trying to gather my toolset. Thanks a lot. :) – ybaylav Nov 26 '14 at 6:38

Here's an example that highlights from ERROR to the end of the line, the whole line containing WARN, and foo but nothing surrounding it. Only the first matching rule is applied (e.g. WARN: ERROR foo sets ERROR foo in red), tune as you see fit.

perl -pe 's/ERROR.*/\e[31m$&\e[0m/ || s/.*WARN.*/\e[33m$&\e[0m/ || s/foo/\e[32m$&\e[0m'

An alternative approach if you want to highlight keywords is to call a function to determine the color of the keyword. (This example doesn't do the same thing as the previous one: it always highlights the whole line.)

perl -pe '
    sub color {
         my ($keyword) = @_;
         $keyword =~ /err/i ? 31 :
         $keyword =~ /warn/i ? 33 :
    if (/(ERROR|WARN|foo)/) {$color=color($1); s/^/\e[${color}m/; s/$/\e[0m/}
  • Why the ||? Why not run all three on each line? You might have a line that matches both ERROR and WARN. – terdon Nov 26 '14 at 0:54
  • @terdon I was giving one example among the many possible desired behaviors. Well, ok, I went for the simpler example: if the patterns nest, you need to remember the active color, or merge them. Ignoring “WARN” on an “ERROR” line is probably the right thing anyway. – Gilles 'SO- stop being evil' Nov 26 '14 at 0:54
  • @Gilles Thanks a lot for the information provided. I'll come back in case of encountering new situations. – ybaylav Nov 26 '14 at 7:03

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.