I'm trying to get each grep command to highlight its results in a different color. I can do it manually with a line like this:
ls -l GREP_COLORS='mt=01;32' grep c | GREP_COLORS='mt=01;31' grep o | GREP_COLORS='mt=01;34' grep n | GREP_COLORS='mt=01;36' grep f
Every c
character will be highlighted in green and every o
character will be highlighted in red, etc…
For this example to work you'll need to ensure that you always have
--color=always
on your grep commands. I've set this in my.bashrc
so grep will always have colors:
export GREP_OPTIONS='--color=always'
What I'm attempting to accomplish is to wrap this functionality with an alias, so I can just call grep
and have a different GREP_COLORS
value each time. I understand the consideration of multiple shells for each new piped grep and I'm trying to over come this by creating some files (one for each color), to indicate that they have already been used.
I have made some attempts but strangely, this one seems to work the "best". I have this in my .bashrc
:
alias mg="mygrep"
mygrep(){
# define possible colors
COLORS=("01;32" "01;31" "01;34" "01;36")
COUNTER=0
NUM=0
# as long as the color has already been used, keep searching
while [ -f /home/lior/Desktop/mygrep_$NUM ]; do
# get a random index
let NUM=`shuf --input-range=0-$(( ${#COLORS[*]} - 1 )) | head -1`
wait ${!}
$(( COUNTER+=1 ))
if [ "$COUNTER" -ge ${#COLORS[@]} ]; then
# remove all color locks
rm /home/lior/Desktop/mygrep_*
wait ${!}
fi
done
# mark this color as used
touch /home/lior/Desktop/mygrep_$NUM
wait ${!}
# lets go!
GREP_COLORS="mt=${COLORS[$NUM]}" grep "$@"
}
I'm using this alias like so:
ll | mg c | mg o | mg n | mg f
The results are quite cool. There are however some errors that are slightly different each time. Here are a couple of screenshots:
Looks like as the shell goes through each pipe command, the previous function did not yet finish its execution. It tries to remove files that don't exist anymore. I'm not to sure where those other command not found
errors are coming from.
As you can see, I've put in some wait
commands to try let the file manipulation complete but this doesn't seem to be working too well. Another thing I have already tried is to use shared memory /dev/shm
but it yielded similar results.
How would I go about getting the results I want?
Note:
I am looking for answers that simply wrap the grep command as it has lots of functionality that I'm wanting to use and intend to insert other logic between the pipes, so I don't want to provide all of the search terms at once. I'm also not looking for other "grep like" tools. Sorry to @terdon who has already posted an awesome perl suggestion.
Best Answer
Here's a different approach. I have a little Perl script which I have already posted in another answer that will highlight the user provided patterns in different colors. A slightly modified version of the script will act like
grep
:If you save that script as
cgrep
somewhere in yourPATH
and make it executable, you can specify up to 10 different patterns, each of which will be printed in a different color: