4
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?

4
  • I don't understand, why aren't you just using the same regex for sed and perl?
    – terdon
    Nov 25, 2014 at 13:46
  • what is the content of log file, and what output you expecting??
    – Hackaholic
    Nov 25, 2014 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, 2014 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, 2014 at 14:14

2 Answers 2

2

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"
1
  • 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, 2014 at 6:38
1

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 :
         32;
    }
    if (/(ERROR|WARN|foo)/) {$color=color($1); s/^/\e[${color}m/; s/$/\e[0m/}
'
3
  • Why the ||? Why not run all three on each line? You might have a line that matches both ERROR and WARN.
    – terdon
    Nov 26, 2014 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. Nov 26, 2014 at 0:54
  • @Gilles Thanks a lot for the information provided. I'll come back in case of encountering new situations.
    – ybaylav
    Nov 26, 2014 at 7:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .