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?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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 nn 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.
Method 2
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.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0