
Estou canalizando a saída de um grep
comando para outro grep
. A primeira grep
é usar --color=always
, para que a primeira correspondência seja colorida. Na prática, isso significa que a correspondência está entre dois códigos de cores, ou seja, \033[1;31m
e \033[0m
.
Agora o problema é que se o segundo padrão for m
, então ele corresponde ao código de cores da correspondência anterior:
echo A B C | grep --color=always A | grep m
Da mesma forma, o número 31
também corresponderia.
Existe alguma maneira de contornar isso?
ATUALIZAR:
Eu esperava que fosse desnecessário dizer que preciso que o fósforo seja colorido, então me livrar dele --color=always
não é uma solução satisfatória para mim.
Responder1
Não use grep --color=always
, é exatamente por isso que o GNU grep
(e talvez outros) também possui grep --color=auto
which é equivalente a grep --color
alone (from man grep
):
--color[=WHEN], --colour[=WHEN]
Surround the matched (non-empty) strings, matching lines,
context lines, file names, line numbers, byte offsets, and
separators (for fields and groups of context lines) with escape
sequences to display them in color on the terminal. The colors
are defined by the environment variable GREP_COLORS. The
deprecated environment variable GREP_COLOR is still supported,
but its setting does not have priority. WHEN is never, always,
or auto.
Não consigo encontrar onde isso está documentado com mais detalhes, mas basicamente detecta se a saída de grep
é um arquivo, um terminal, um canal ou qualquer outra coisa e age de acordo:
$ echo foo | grep --color=always o | grep m
f[01;31mo[m[01;31mo[m
$ echo foo | grep --color=always o >outfile; grep m outfile
f[01;31mo[m[01;31mo[m
Compare o acima com
$ echo foo | grep --color o >outfile; grep m outfile
$ echo foo | grep --color o | grep m
$
Portanto, usar a auto
opção basicamente só imprimirá as cores quando você puder vê-las. É realmente muito inteligente e funciona perfeitamente. Tanto é que eu tenho:
$ type grep
grep is aliased to `grep --color'
Responder2
Pelo que vale, esta é exatamente a razão pela qual --color
o padrão é --color=auto
e não --color=always
.
Se o seu objetivo é "Mostre-me todas as linhas que contêm A
e m
realcem a correspondência A
e m
os caracteres", parece que a solução mais simples seria fazer todo o destaque depois de toda a correspondência, usando um egrep para adicionar o destaque novamente. Algo como:
{
echo "A b";
echo "A m";
echo "B m";
echo "Another m";
} | grep 'A' | grep 'm' | egrep --color 'A|m';
Responder3
Qual é o caso de uso real? Se você quiser codificar por cores A
todas as linhas que também contêm, m
você pode simplesmente inverter o grep
s:
echo A B C | grep m | grep --color=always A
Alternativamente, se você estiver procurando por um literal m
na saída original, precisará excluir todos os códigos de cores antesgrep m
mas imprimir o resultadocomos códigos de cores. Uma maneira de fazer isso é usar nl
para numerar as linhas da saída, grep
para um número de linha seguido por m
, salvar apenas os números de linha dessa saída e, em seguida, usar sed -n
para imprimir apenas as linhas na saída codificada por cores.