soreau
soreau

Reputation: 149

Different results in grep results when using --color=always option

I ran into this problem with grep and would like to know if it's a bug or not. The reproducible scenario is a file with the contents:

string
string-

and save it as 'file'. The goal is to use grep with --color=always to output 'string' while excluding 'string-'. Without --color, the following works as expected:

$ grep string file | grep -v string-

but using --color outputs both instances:

$ grep --color=always string file | grep -v string-

I experimented with several variations but it seems --color breaks the expected behavior. Is this a bug or am I misunderstanding something? My assumption is that passing --color should have no effect on the outcome.

Upvotes: 3

Views: 1223

Answers (2)

mklement0
mklement0

Reputation: 437408

@Jake Gould's answer provides a great analysis of what actually happens, but let me try to phrase it differently:

--color=always uses ANSI escape codes for coloring.

In other words: --color=always by design ALTERS its output, because it must add the requisite escape sequences to achieve coloring.

Never use --color=always, unless you know the output is expected to contain ANSI escape sequences - typically, for human eyeballs on a terminal.

If you're not sure how the input is processed, use --color=auto, which - I believe - causes grep to apply coloring only if its stdout is connected to a terminal.

I a given pipeline, it typically only makes sense to apply --color=auto (or --color=always) to a grep command that is the LAST command in the pipeline.

Upvotes: 2

Giacomo1968
Giacomo1968

Reputation: 26066

When you use --color grep adds ANSI (I believe?) color coding. So your text which looks like this:

string
string-

Will actually look like this in terms of pure, unprocessed ASCII text:

^[[01;31m^[[Kstring^[[m^[[K
^[[01;31m^[[Kstring^[[m^[[K-

There is some nice info provided in this question thread including this great this answer.

My assumption is that passing --color should have no effect on the outcome.

Nope. The purpose of grep—as most all Unix/Linux tools—is to provide a basic simple service & do that well. And that service is to search a plain-text (key here) input file based on a patter & return the output. The --color option is a small nod to the fact that we are humans & staring at screens with uncolored text all day can drive you nuts. Color coding makes work easier.

So color coding with ANSI is usually considered a final step in a process. It’s not the job of grep to assume that if it comes across ANSI in it’s input it should ignore it. Perhaps a case could be made to add a --decolor option to grep, but I doubt that is a feature worth the effort.

grep is a base level plain-text parsing tool. Nothing more & nothing less.

Upvotes: 2

Related Questions