Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am piping output of one grep comand 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.

share|improve this question
5  
Stop using --color=always? –  Hauke Laging Jun 24 at 11:44
    
    
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 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. –  Martin Vegter Jun 24 at 13:54
    
@MartinVegter see godlygeek's answer. It describes how you can use egrep to do the final coloring. –  jofel Jun 24 at 16:55

3 Answers 3

up vote 3 down vote accepted

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';
share|improve this answer

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'
share|improve this answer
    
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 at 11:59

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.