grep em cascata corresponde ao código de cor como padrão

5

Estou enviando a saída de um comando grep para outro grep . O primeiro grep está usando --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, por exemplo, 3[1;31m e 3[0m .

Agora, o problema é que, se o segundo padrão for m , ele corresponderá 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?

UPDATE:

Eu esperava que fosse desnecessário dizer que eu preciso que a partida seja colorida, então me livrar de --color=always não é uma solução satisfatória para mim.

    
por Martin Vegter 24.06.2014 / 13:34

3 respostas

3

Por que vale a pena, essa é exatamente a razão pela qual o --color é padronizado como --color=auto e não --color=always .

Se sua meta for "Mostre-me todas as linhas que contêm A e m e realce os caracteres A e m " correspondentes, parece que a solução mais simples seria fazer todo o realce após toda a correspondência, usando um egrep para adicionar o realce de volta. Algo como:

{
    echo "A b";
    echo "A m";
    echo "B m";
    echo "Another m";
} | grep 'A' | grep 'm' | egrep --color 'A|m';
    
por 24.06.2014 / 15:05
6

Não use grep --color=always , é exatamente por isso que o GNU grep (e talvez outros) também tem grep --color=auto , que é equivalente a grep --color sozinho (de 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.

Eu não consigo encontrar onde isso está documentado em mais detalhes, mas ele basicamente detecta se a saída de grep é um arquivo ou um terminal ou um pipe 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 opção auto basicamente só imprimirá as cores quando você as puder ver. É realmente muito inteligente e funciona como um encanto. Tanto que eu tenho:

$ type grep
grep is aliased to 'grep --color'
    
por 24.06.2014 / 13:56
2

Qual é o caso de uso real? Se você quiser colorir o código A em 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

Como alternativa, se você estiver procurando por um literal m na saída original, precisará excluir todos os códigos de cores antes de grep m , mas imprimir o resultado com os 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 usar sed -n para imprimir somente as linhas na saída codificada por cores.

    
por 24.06.2014 / 13:49

Tags