Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grep output with multiple Colors?

Is there an elegant method in bash for running grep against a text file with two or more patterns, and each pattern that matches is output in a different color?

So a line that matches on MALE and AUGUST would output MALE in blue and AUGUST in orange? I am open to the use of sed, awk, grep and crayons or others.

like image 579
Evil Genius Avatar asked Jun 21 '13 13:06

Evil Genius


2 Answers

You can cascade greps with different colors by specifying --color=always and using the regular expression 'foo|$' to pass all lines.

For example:

tail -f myfwlog | GREP_COLOR='01;36' egrep --color=always 'ssh|$' | GREP_COLOR='01;31' egrep -i --color=always 'drop|deny|$' 

If you want the entire line to be highlighted, update your regular expression accordingly:

.... GREP_COLOR='01;31' egrep -i --color=always '^.*drop.*$|^.*deny.*$|$' 
like image 178
Rob Windsor Avatar answered Sep 21 '22 00:09

Rob Windsor


grep is a regular expression matcher, not a syntax highlighter :). You'll have to use multiple invocations of grep, using a different value of GREP_COLOR for each.

GREP_COLOR="1;32" grep foo file.txt | GREP_COLOR="1;36" grep bar 

That would highlight "foo" and "bar" in different colors in lines that match both. I don't think there is a (simple) way to handle all occurrences of either pattern, short of merging the output stream of two independent calls:

{ GREP_COLOR="1;32" grep foo file.txt   GREP_COLOR="1;36" grep bar file.txt } | ... 

which will obviously look different than if there were a way to assign a separate color to each regular expression.


You can use awk to substitute each match with itself wrapped in the correct control code.

 echo "foo bar" | awk '{ gsub("bar", "\033[1;33m&\033[0m");                          gsub("foo", "\033[1;36m&\033[0m"); print }' 

In each line, you globally replace anything matching the given regular expression with itself (&) wrapped in the ANSI escape sequences for desired color (which grep --color does for you). After processing all of the possible matches, you need to explicitly print the line.

like image 26
chepner Avatar answered Sep 22 '22 00:09

chepner