5

I am piping output of one grep command into another grep. The first grep is using --color=always, so that the first match is colored. In practice, that means that the match is enclosed between two color codes, i.e. \033[1;31m and \033[0m.

Now the problem is if the second pattern is m, then it matches the color code of the previous match:

echo A B C | grep --color=always A | grep m

Similarly, the number 31 would also match.

Is there any way around this?

UPDATE:

I expected it will go without saying that I need the match to be colored, so getting rid of --color=always is not a satisfactory solution for me.

6
  • 5
    Stop using --color=always? Jun 24, 2014 at 11:44
  • See also unix.stackexchange.com/q/9360/22565 Jun 24, 2014 at 12:09
  • What do you really want to search for and which parts do you want to have colored? Probably you can use only one call to egrep and concatenate the patterns with "|".
    – jofel
    Jun 24, 2014 at 13:28
  • @jofel - I don't want to match "A or B" but I want to match "A and B". Thus, egrep does not help me here. Jun 24, 2014 at 13:54
  • @MartinVegter see godlygeek's answer. It describes how you can use egrep to do the final coloring.
    – jofel
    Jun 24, 2014 at 16:55

3 Answers 3

6

Don't use grep --color=always, that's precisely why GNU grep (and maybe others) also have grep --color=auto which is equivalent to grep --color alone (from man grep):

   --color[=WHEN], --colour[=WHEN]
          Surround  the  matched  (non-empty)  strings,  matching   lines,
          context  lines,  file  names,  line  numbers,  byte offsets, and
          separators (for fields and groups of context lines) with  escape
          sequences  to display them in color on the terminal.  The colors
          are  defined  by  the  environment  variable  GREP_COLORS.   The
          deprecated  environment  variable GREP_COLOR is still supported,
          but its setting does not have priority.  WHEN is never,  always,
          or auto.

I can't find where this is documented in more detail but it basically detects whether the output of grep is a file or a terminal or a pipe or whatever and acts accordingly:

$ echo foo | grep --color=always o | grep m
f[01;31mo[m[01;31mo[m
$ echo foo | grep --color=always o >outfile; grep m outfile
f[01;31mo[m[01;31mo[m

Compare the above to

$ echo foo | grep --color o >outfile; grep m outfile
$ echo foo | grep --color o | grep m 
$ 

So, using the auto option will basically only print the colors when you can see them. It is really very clever and works like a charm. So much so, that I have:

$ type grep
grep is aliased to `grep --color'
1
  • agreed - this can be especially problematic when compiling. any compilation job worth its salt is likely to call grep hundreds of times throughout the process. gcc will get pretty upset if grep keeps spitting terminal escapes at it.
    – mikeserv
    Jun 24, 2014 at 11:59
3

For what it's worth, this is exactly the reason why --color defaults to --color=auto and not --color=always.

If your goal is "Show me all lines that contain both A and m and highlight the matching A and m characters", it seems like the simplest solution would be to do all the highlighting after all of the matching, using one egrep to add the highlighting back in. Something like:

{
    echo "A b";
    echo "A m";
    echo "B m";
    echo "Another m";
} | grep 'A' | grep 'm' | egrep --color 'A|m';
0
2

What is the actual use case? If you want to colour code A in all lines which also contain m you can simply reverse the greps:

echo A B C | grep m | grep --color=always A

Alternatively, if you're looking for a literal m in the original output you'd need to exclude all the colour codes before grep m but print the result with the colour codes. One way to do this is to use nl to number the lines of the output, grep for a line number followed by m, save only the line numbers from that output, and then use sed -n to print only the lines in the colour coded output.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .