Você pode fazer o truque com a opção -E
:
grep -E '(^|pattern)' file
Aqui está uma saída simples:
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?
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 ").
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.
Isso é embutido em ack - a saída colorida é o padrão, e a opção --passthru
imprime todas as linhas.
Tags grep text-processing