You can change this behavior by setting the GREP_COLORS
environment variable:
export GREP_COLORS=ne
echo -e "ab\rc" | grep --color=always "c"
From the grep
man page:
ne Boolean value that prevents clearing to the end of line
using Erase in Line (EL) to Right (\33[K) each time a
colorized item ends. This is needed on terminals on
which EL is not supported. It is otherwise useful on
terminals for which the back_color_erase (bce) boolean
terminfo capability does not apply, when the chosen
highlight colors do not affect the background, or when EL
is too slow or causes too much flicker. The default is
false (i.e., the capability is omitted).
It's done in the first place to set the background of the rest of the line to the correct color, in case it was changed earlier (though by default it isn't; somebody might set it up to do so in their own settings).
You may also want to play with the other options that can be set in GREP_COLORS
; see the man page for full details.
If grep o
produces color output, then either grep
is an alias to grep --color=auto
or grep --color=always
(or possibly more options), or GREP_OPTIONS
is set to a value that contains --color=auto
or --color=always
. Since $GREP_OPTIONS
is empty, it must be the alias.
Since grep o | less -R
doesn't show colors, the alias must be to grep --color=auto
(a sensible choice). With the alias, the grep
command always receives the --color
option on the command line, and this takes precedence over the environment variable.
If you want to use the environment variable, remove the alias definition from your ~/.bashrc
, or for one session run unalias grep
. You can replace alias grep='grep --color=auto'
by export GREP_OPTIONS='--color=auto'
: they have essentially the same meaning, except that:
- setting
GREP_OPTIONS
to a different value only overrides the latter;
- the alias only kicks in when you run
grep
from an interactive shell, whereas setting GREP_OPTIONS
also applies when grep
is run from scripts and other applications.
Never put --color=always
or most other options in GREP_OPTIONS
: it would break many programs that parse the output of grep
. --color=auto
is about the only safe option to put in GREP_OPTIONS
. For anything else, use the alias. Future versions of GNU grep will drop support for the option for this reason.
Note that the alias definition goes into ~/.bashrc
(it's a shell setting), whereas the environment variable definition goes into ~/.profile
(it's a session setting). See Is there a ".bashrc" equivalent file read by all shells?
If you want to run the unaliased command just once, run \grep
instead of grep
(quoting any part of the name bypasses the alias lookup).
Best Answer
Finding the discrepancy
I spent some time poking through the source code for grep and narrowed down the problem a bit.
The main issue lies in the function
print_line_middle
. See this loop construct:The discrepancy
The issue is that for example #3 above, the
match_offset = execute(...)
call is equal to -1. This result influences when the printing is done and thereby what colors are used.Is this a bug?
I have no idea :) but feel free to send the devs an email. From the README: