Correspondência de cores, mas também imprime outras linhas [duplicadas]

5

Eu tenho um alias: alias grep='grep --color=auto' . Eu gostaria de ter uma maneira de imprimir não apenas a linha correspondente, mas todas elas e apenas padrões de correspondência de cores. Duvido que exista uma opção para fazer isso no grep em si. Alguma outra ferramenta? Ou ideia de como conseguir isso?

    
por pawel7318 29.04.2014 / 15:47

4 respostas

10

Você pode fazer o truque com a opção -E :

grep -E '(^|pattern)' file

Aqui está uma saída simples:

    
por 29.04.2014 / 15:55
4

Você pode fazer isso usando um pouco sed e a mágica do terminal:

$ sed -e 's/<pattern>/\x1b[31;01m&\x1b[m/g' <file>

Isso substitui cada ocorrência de <pattern> pelo texto correspondente cercado por \x1b[31;01m (que é a sequência de escape do terminal para "definir cor de primeiro plano para negrito vermelho") e \x1b[m (mesmo para "definir cor de primeiro plano como padrão ").

    
por 29.04.2014 / 15:55
2

Eu escrevi um pequeno script que irá colorir qualquer string que você der:

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

my %opts;
getopts('hic:l:',\%opts);
    if ($opts{h}){
      print<<EoF; 
Use -l to specify the pattern(s) to highlight. To specify more than one 
pattern use commas. 

-l : A Perl regular expression to be colored. Multiple expressions can be
     passed as comma separated values: -l foo,bar,baz
-i : makes the search case sensitive
-c : comma separated list of colors;

EoF
      exit(0);
    }

my $case_sensitive=$opts{i}||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');
if ($opts{c}) {
   @color=split(/,/,$opts{c});
}
my @patterns;
if($opts{l}){
     @patterns=split(/,/,$opts{l});
}
else{
    $patterns[0]='\*';
}

# 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ê salvá-lo como color em um diretório que esteja no seu $PATH e torná-lo executável ( chmod +x /usr/bin/color ), poderá colorir o padrão correspondente assim:

echo -e "foo\nbar\nbaz\nbib" | color -l foo,bib 

Isso produzirá:

Como escrito, o script tem cores predefinidas para 10 padrões diferentes, portanto, dar a ela uma lista separada por vírgulas como no exemplo acima colourará cada um dos padrões combinados em uma cor diferente.

    
por 29.04.2014 / 15:51
2

Isso é embutido em ack - a saída colorida é o padrão, e a opção --passthru imprime todas as linhas.

    
por 29.04.2014 / 17:31