Why grepping with color doesn’t return anything

bsdcommand linegreposx

I've got the following foo.txt file:

This is the first line.
This is the middle line.
This is the last line.

And I'm trying to grep the middle line just by the word middle and return the surroundings (as example), so I can highlight the whole sentence (which is especially useful when using with context option).

It does work without the color:

$ grep -o --color=none '.\+ middle .\+' foo.txt
This is the middle line.

But the same command doesn't work with color:

$ grep -o --color=auto '.\+ middle .\+' foo.txt
(empty line)

Note: Without -o it doesn't make any difference.

Although it works when filtering only the first half of the line:

$ grep -o --color=auto '.\+ middle' foo.txt
This is the middle

but not with the second half ('middle .\+').

Why this doesn't work as expected and how can I fix it? Is it a bug or I can't use two regex expressions at the same time for some reason?


Tested on OS X with:

$ grep --version
grep (BSD grep) 2.5.1-FreeBSD

Although it seems to work on Linux, so I'm confused.

Best Answer

When you use grep with color options it produces extra escape character sequences which tell the terminal to turn color on or off, these sequences introduce a risk of not being interpreted properly and causing unexpected results.
You can view these by capturing grep's output

With no color

send greps output to output.txt

% grep -o --color=none '.\+ middle .\+' foo.txt > output.txt
% cat -etv output.txt 
This is the middle line.$

With color

Forcing color with the --color=always option. If you redirect greps output it will - if possible - turn off color for the exact reason you have highlighted, the escape characters may produce side effects.

% grep -o --color=always '.\+ middle .\+' foo.txt > output.txt
% cat -etv output.txt                                             
^[[01;31m^[[KThis is the middle line.^[[m^[[K$

It is possible these escape sequences are causing the problem.

Related Question