Zitrax
Zitrax

Reputation: 20256

Preserve colouring after piping grep to grep

There is a simlar question in Preserve ls colouring after grep’ing but it annoys me that if you pipe colored grep output into another grep that the coloring is not preserved.

As an example grep --color WORD * | grep -v AVOID does not keep the color of the first output. But for me ls | grep FILE do keep the color, why the difference ?

Upvotes: 202

Views: 60560

Answers (4)

Sridhar Sarnobat
Sridhar Sarnobat

Reputation: 25236

The existing answers only address the case when the FIRST command is grep (as asked by the OP, but this problem arises in other situations too).

More general answer

The basic problem is that the command BEFORE | grep, tries to be "smart" by disabling color when it realizes the output is going to a pipe. This is usually what you want so that ANSI escape codes don't interfere with your downstream program.

But if you want colorized output emanating from earlier commands, you need to force color codes to be produced regardless of the output sink. The forcing mechanism is program-specific.

Git: use -c color.status=always

git -c color.status=always status | grep -v .DS_Store

Note: the -c option must come BEFORE the subcommand status.

Others

(this is a community wiki post so feel free to add yours)

Upvotes: 33

Alex
Alex

Reputation: 6037

Simply repeat the same grep command at the end of your pipe.
grep WORD * | grep -v AVOID | grep -v AVOID2 | grep WORD

Upvotes: 13

andersonvom
andersonvom

Reputation: 11851

A word of advice:

When using grep --color=always, the actual strings being passed on to the next pipe will be changed. This can lead to the following situation:

$ grep --color=always -e '1' * | grep -ve '12'
11
12
13

Even though the option -ve '12' should exclude the middle line, it will not because there are color characters between 1 and 2.

Upvotes: 84

Otto Allmendinger
Otto Allmendinger

Reputation: 28268

grep sometimes disables the color output, for example when writing to a pipe. You can override this behavior with grep --color=always

The correct command line would be

grep --color=always WORD * | grep -v AVOID

This is pretty verbose, alternatively you can just add the line

alias cgrep="grep --color=always"

to your .bashrc for example and use cgrep as the colored grep. When redefining grep you might run into trouble with scripts which rely on specific output of grep and don't like ascii escape code.

Upvotes: 217

Related Questions