12

I need grep output with context, in color, and blank lines as group separator. In this question, I learned how to define custom group-separator, and I have constructed my grep command like this:

grep --group-separator="" --color=always -A5

but the group separator is actually not empty, instead it still contains the color code (i.e. [[36m[[K[[m[[K). This is because I am using --color=always. But I need color in my grep command, and I need separator to be blank line (for further processing)

How can I combine these two conditions?

Martin Vegter
  • 69
  • 66
  • 195
  • 326
  • If you have `--color=always` the match will print with color, and if you have the `--group-separator=""` set to the empty string you will get a blank line after your matching group. Please try again leaving the `--group-separator=""` with the empty string, not a specific color escape, and then explain what is not working. – bsd Feb 04 '14 at 21:12
  • @bdowning that's what the OP tried. The code he mentions is not visible in the terminal output. Try passing the output through `od -c` to see the hidden characters that appear in the blank lines. – terdon Feb 04 '14 at 21:20
  • @terdon, I see it with `od`. – bsd Feb 04 '14 at 22:37

2 Answers2

10

If you use the GREP_COLORS environment variable you can control specific colors for each type of match. man grep explains the use of the variable.

The following command will print a colored match, but nothing on the line that separates the group, just a blank line. Piped through od you'll see the color escape before and after the match, but only \n\n at the group separation.

GREP_COLORS='ms=01;31:mc=01;31:sl=:cx=:fn=35:ln=32:bn=32:se=' grep --group-separator="" --color=always -A5

Unsetting the se component will suppress the printing of color in the group separator.

Since my example above used all of the default values for GREP_COLORS the following will work as well.

GREP_COLORS='se=' grep --group-separator="" --color=always -A5

If you're not using a bashlike shell, you might need to export GREP_COLORS first.

bsd
  • 10,916
  • 4
  • 30
  • 38
5

Personally, I do that using Perl, not grep. I have a little script that will highlight a given pattern in color:

#!/usr/bin/env perl
use Getopt::Std;
use strict;
use Term::ANSIColor; 

my %opts;
getopts('hsc:l:',\%opts);
    if ($opts{h}){
      print<<EoF; 
DESCRIPTION

$0 will highlight the given pattern in color. 

USAGE

$0 [OPTIONS] -l PATTERN FILE

If FILE is ommitted, it reads from STDIN.

-c : comma separated list of colors
-h : print this help and exit
-l : comma separated list of search patterns (can be regular expressions)
-s : makes the search case sensitive

EoF
      exit(0);
    }

my $case_sensitive=$opts{s}||undef; 
my @color=('bold red','bold blue', 'bold yellow', 'bold green', 
           'bold magenta', 'bold cyan', 'yellow on_magenta', 
           'bright_white on_red', 'bright_yellow on_red', 'white on_black');
## user provided color
if ($opts{c}) {
   @color=split(/,/,$opts{c});
}
## read patterns
my @patterns;
if($opts{l}){
     @patterns=split(/,/,$opts{l});
}
else{
    die("Need a pattern to search for (-l)\n");
}

# Setting $| to non-zero forces a flush right away and after 
# every write or print on the currently selected output channel. 
$|=1;

while (my $line=<>) 
{ 
    for (my $c=0; $c<=$#patterns; $c++){
    if($case_sensitive){
        if($line=~/$patterns[$c]/){
           $line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ge;
        }
    }
    else{
        if($line=~/$patterns[$c]/i){
          $line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ige;
        }
      }
    }
    print STDOUT $line;
}

If you save that in your path as color, you can get your desired output by running

grep --group-separator="" --color=never -A5 foo | color -l foo

That way, the script is coloring the matches for you and you can tell grep not to use colors and avoid this problem.

terdon
  • 234,489
  • 66
  • 447
  • 667
  • Please, @terdon add it to a [gist](https://gist.github.com/), and link it back here, so it will be easier to follow any evolution. – Rafareino Aug 19 '15 at 22:40
  • @Rafareino yeah, I'm afraid I don't really use such tools. I do actually have a repository but it is very rarely updated. I keep meaning to set one up and use it properly but I never seem to get round to it. – terdon Sep 03 '15 at 12:18
  • So I made a small correction right here, sadly, I needed to include a comment to reach the minimum edit @terdon – Rafareino Sep 04 '15 at 14:17