22

If I use two consecutive grep commands, e.g.:

echo "foo bar" | grep foo | grep bar

Then the first pattern ("foo") is not highlighted. In fact, it seems that grep removes color codes from its input. Is there any way to prevent this?

yoniLavi
  • 151
Chris2048
  • 601

1 Answers1

32

Use --color=always.

grep detects if output is to a pipe (or file). You most never want colors when output is to file – as that is escape sequences for the terminal. Typically:

foo ^[[01;31m^[[Kbar^[[m^[[K

from e.g.:

grep pattern file > result

To override use --color=always.

grep --color=always pattern file | ...

Example:

Having file:

ID=111;Year=2013;foo=bar
ID=222;Year=2013;foo=baz

Then

grep --color=always ID file | grep --color=always 2013 | grep foo

would color ID, 2013 and foo.

grep --color=always ID file | grep 2013 | grep foo

would color ID and foo, but not 2013.

1Important: You also have to remember that the added clutter from colors is passed to next command in the chain. Once ID is colored, you can't (with ease), match e.g. ID=111.


On some occasion one would perhaps want terminal colors in file. Try e.g.

 grep --color=always foo file > result
 cat result

Though the resulting file would have very limited portability.


The coloring itself is also an extension.


As mentioned by the good @slm, you could add:

export GREP_OPTIONS="--color=always"

to your .bashrc etc, but don't unless you for some reason really understand the implications and still want to do it. It would in many ways break grep due to the fact mentioned above 1.

Add an alias if you use it often.

 alias cgrep='grep --color=always'

GREP_OPTIONS and --color take three options: never, auto and always. The two first should be the only ones considered for GREP_OPTIONS.

You could also check out GREP_COLORS in the man pages or at gnu grep.

Runium
  • 28,811
  • Additional details on this methods pros/cons here: http://stackoverflow.com/questions/867877/preserve-ls-colouring-after-greping – slm May 12 '13 at 15:46
  • 4
    add this to the answer too: export GREP_OPTIONS="--color=always" in a .bashrc makes the options the defaults for any greps, and you've pretty much nailed it! – slm May 12 '13 at 15:53
  • Good stuff in this Super Uuser Q&A: http://superuser.com/questions/36022/less-and-grep-getting-colored-results-when-using-a-pipe-from-grep-to-less – slm May 12 '13 at 15:54
  • "grep detects if output is to a pipe" -- aha! This is the key, grep isn't coloring if it's part of a pipe. There should be a substitution principle against this sort of thing :-/ – Chris2048 May 12 '13 at 16:11
  • @Chris2048: This is standard for most tools printing colors to terminal. You might find some more detail by this, on how it is detected, And this show some issues by e.g. ls and colors on OSX native ls and gnu coreutils. – Runium May 12 '13 at 16:24
  • 2
    export GREP_OPTIONS="--color=always" is deprecated (2019), and 'alias cgrep='grep --color=always''' isn't available inside bash functions. – mosh May 15 '19 at 17:54
  • 3
    How do I make grep preserve colors from piped input and NOT add color to the match (i.e. only use grep to filter lines)? – geekley Nov 14 '20 at 00:25