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.
alias mg="mygrep; grep"
? – Bernhard Dec 09 '13 at 11:16mygrep;
turns into a new command in itself and the data stream get's lost. The incoming pipe from thels
would get passed tomygrep;
and not to grep. At least that is how I understand it. – Lix Dec 09 '13 at 11:22--color=always
on all your grep commands. I've set that globally in my.bashrc
. I've edited that into the post. – Lix Dec 09 '13 at 11:27GREP_COLORS
parameter before thegrep
command, I could also add--color=always
to ensure it'll work even after several pipes. – Lix Dec 09 '13 at 12:32alias
has some limitations as you notice. I'd just encapsulate this in a script, call itmygrep
or whatever and put it in~/bin
, presuming that's in your$PATH
. – goldilocks Dec 09 '13 at 16:10