Home > Software design >  Howto grep 2 words to be highlighted
Howto grep 2 words to be highlighted

Time:01-14

I've seen few similar questions, but none answers this problem.
I'd like to search a maillog for status of emails to particular user/domain. So I need to grep for email (ie @gmail.com) and status (ie '=sent'). I know I can just do one after another, but I would like to have both words highlighted! So if I can do it:
grep 'gmail.com' /var/log/maillog -A 2 -B 2|grep '=sent'
only "=sent" will be highlighted. If I do it:
grep 'gmail.com.*=sent' /var/log/maillog -A 2 -B 2
Then everything in between will also be highlighted.
Using -P option it wouldn't highlight matched pattern. awk I also wasn't able to get this result

CodePudding user response:

grep implementations that color their output usually have a default setting of --color=auto that inserts color codes only when printing to a terminal. When printing to a file or pipe, color is automatically disabled, but can be enabled manually.

Since your search strings gmail.com and =sent can never overlap*, you can just enable --color=always and run the colored output through grep again. Here I also

grep -C2 --color=always -F 'gmail.com' /var/log/maillog |
grep -aC2 '=sent'

* In general, this trick does not work. Assume you where searching ab and bc in the line abc, then the first command would print …ab…c where are invisible escape sequences that tell your terminal how to color the text. Because of those escape sequences, the second command would print nothing, because bc is not in the output; only b…c is, but that is something different.

Note: I mostly copied your approach with -A2 -B2 which contains a few flaws. Possible fixes depend on your precise requirements.

CodePudding user response:

Maybe with this?

grep 'gmail\.com.*=sent' /var/log/maillog -A 2 -B 2 |
grep -F -e 'gmail.com' -e '=sent' -A 2 -B 2

CodePudding user response:

With awk and the red color:

awk '/gmail\.com/ && /=sent/ {gsub(/gmail\.com|=sent/,"\033[01;31m&\033[0m"); print}'

With sed (and bash):

sed -E $'/gmail\.com/{/=sent/s/(gmail\.com|=sent)/\033[01;31m&\033[0m/g}'
  • Related