可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Is there a elegant method in bash of running grep against a text file with 2 or more patterns, and each pattern that matches is output in a different color?
So a line that matches on MALE
and AUGUST
would out put MALE
in blue and AUGUST
in orange?
I am open to the use of sed
, awk
, grep
and crayons or other...
回答1:
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.*$|$'
回答2:
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.
回答3:
If you want something out of the box, you're probably looking for hhighlighter.
Here's an example:
Take a look. It's incredibly useful for coloring words in different colors automatically. It's an impressive project that's built on top of ack.
回答4:
I had the need to highlight strings in text files, and did not find a way that suited my needs, so I wrote a simple C program to colorize strings matching regular expressions.
You can download the source code from GitHub :
git clone http://github.com/mbornet-hl/hl
then :
cd hl/cr; make
Here is the usage :
hl: version 1.21
Usage: hl [-h|-eidD][-E][-rgybmcwRGYBMCW] regexp ...
-h : help
-v : version
-u : do not bufferize output on stdout
-e : extended regular expressions
-i : ignore case
-E : print on stderr
-r : red
-g : green
-y : yellow
-b : blue
-m : magenta
-c : cyan
-w : white
-R : red (reverse video)
-G : green (reverse video)
-Y : yellow (reverse video)
-B : blue (reverse video)
-M : magenta (reverse video)
-C : cyan (reverse video)
-W : white (reverse video)
-d : debug
-D : display regular expressions
To colorize the word "red" in red, and the word "blue" in blue, you just have to type in the following command :
echo "red blue red blue" | hl -r red -b blue
and here is an example to highlight the output of the ifconfig command :
hl -ei -m '^(eth|(vir)?br|vnet)[0-9.]*:[0-9]+\>' \
-b '^(eth|(vir)?br|vnet)[0-9.]*\.[0-9]+\>' \
-c '([0-9a-f]{2}:){5}[0-9a-f]{2}' \
-g '\<UP\>|\<RUNNING\>|([0-9]{1,3}\.){3}[0-9]{1,3}\>' \
-y '^(eth|(vir)?br|vnet)[0-9.:]*\>' \
-W '[0-9a-f]{4}::[0-9a-f]{4}\:[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}' \
-r ' (errors|dropped|overruns):[^0][0-9]*'
The order in which you specify the colors is important : if a string matches several regular expressions, the 1st one as a higher priority than the 2nd one, the 2nd one as a higher priority than the 3rd one, and so on ...
Hope This Helps.
回答5:
Try the wonderful rpen http://github.com/rtulke/rpen
require egrep or grep
cp rpen.py /usr/local/bin/rpen
chmod 777 /usr/local/bin/rpen
then try
ps xau |rpen Ss "S+" "\?\?"
回答6:
So here's the version(s) using sed. Let's say you want the word "FAILED" to be colored red, that would be:
sed 's/\(ERROR\)/\o033[31m\1\o033[39m/'
To have the whole line containing the word "FAILED" marked in red:
sed 's/\(.*ERROR.*\)/\o033[31m\1\o033[39m/'
To have multiple words marked red:
sed 's/\(ERROR\|FAILED\)/\o033[31m\1\o033[39m/'
To have multiple words and their wohle lines marked in red:
sed 's/\(.*FAILED.*\|.*ERROR.*\)/\o033[31m\1\o033[39m/'
To have multiple colors (ERROR=red/FAILED=blue)
sed -e 's/\(ERROR\)/\o033[31m\1\o033[39m/' -e 's/\(FAILED\)/\o033[34m\1\o033[39m/'
To use all this over ssh:
ssh user@host -t "tail -n 1024 -f /some/log/file | sed --unbuffered -e 's/\(.*ERROR.*\|.*FAILED.*\)/\o033[31m\1\o033[39m/' -e 's/\(.*postfix.*\|.*dhcpd.*\)/\o033[32m\1\o033[39m/'"
And for not having to type this everytime, just declare it as a function in your bashrc.
For other colors look up ANSI codes.
回答7:
How about this? You can do it with grep ONLY! Tricks here are (1) you take /OR/ of the words you are searching; (2) you use -A and -B options with large enough numbers (larger then the line count of your file).
echo "you make it" > tmp
echo "you take it" >> tmp
echo "you cake it" >> tmp
echo "you bake it" >> tmp
echo "you wake it" >> tmp
GREP_COLOR='1;32' grep -P "(take|cake|bake)" --color=always tmp | GREP_COLOR='1;33' grep -P "(cake|bake)" --color=always -A10000 -B10000 | GREP_COLOR='1;34' grep -P "(bake)" --color=always -A10000 -B10000
回答8:
cxpgrep is right for this purpose - highlight patterns in different colors.
cxpgrep 'PAT1|PAT2|...' FILE_OR_DIRECTORY
回答9:
My answer is below:
tailf logfile awk '/MALE/' {print "\033[34m" $0 "\033[39m"} '/MALE/' {print "\033[33m" $0 "\033[39m"}