Usando linha vazia como contexto “separador de grupo” para grep

12

Eu preciso da saída do grep com contexto, em cores e linhas em branco como separador de grupo. Neste pergunta , aprendi como definir o group-separator personalizado e construí meu comando grep assim:

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

mas o separador de grupo não está realmente vazio, em vez disso, ele ainda contém o código de cor (por exemplo, [[36m[[K[[m[[K ). Isso é porque estou usando --color=always . Mas eu preciso de cor no meu comando grep, e eu preciso de separador para ser linha em branco (para processamento adicional)

Como posso combinar essas duas condições?

    
por Martin Vegter 04.02.2014 / 17:14

2 respostas

9

Se você usar a variável de ambiente GREP_COLORS , poderá controlar cores específicas para cada tipo de correspondência. man grep explica o uso da variável.

O comando a seguir imprimirá uma correspondência colorida, mas nada na linha que separa o grupo, apenas uma linha em branco. Conduzido através de od , você verá a cor escapar antes e depois da partida, mas apenas \n\n na separação do grupo.

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

Desvincular o componente se suprimirá a impressão de cores no separador de grupos.

Como meu exemplo acima usou todos os valores padrão para GREP_COLORS , o seguinte também funcionará.

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

Se você não estiver usando um shell semelhante a bash , talvez seja necessário exportar GREP_COLORS primeiro.

    
por 05.02.2014 / 12:08
5

Pessoalmente, faço isso usando Perl, não grep . Eu tenho um pequeno script que irá destacar um determinado padrão em cores:

#!/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;
}

Se você salvar isso em seu caminho como color , poderá obter a saída desejada executando

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

Dessa forma, o script está colorindo as correspondências para você e você pode dizer a grep para não usar cores e evitar esse problema.

    
por 04.02.2014 / 22:23