
Estoy canalizando la salida de un grep
comando a otro grep
. El primero grep
es usar --color=always
, para que se coloree la primera coincidencia. En la práctica, eso significa que la coincidencia se incluye entre dos códigos de color, es decir \033[1;31m
y \033[0m
.
Ahora el problema es que si el segundo patrón es m
, entonces coincide con el código de color de la coincidencia anterior:
echo A B C | grep --color=always A | grep m
Del mismo modo, el número 31
también coincidiría.
¿Hay alguna manera de evitar esto?
ACTUALIZAR:
Esperaba que fuera innecesario decir que necesito colorear la cerilla, por lo que deshacerme de ella --color=always
no es una solución satisfactoria para mí.
Respuesta1
No use grep --color=always
, es precisamente por eso que GNU grep
(y tal vez otros) también tienen grep --color=auto
lo que equivale a grep --color
solo (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.
No puedo encontrar dónde está documentado esto con más detalle, pero básicamente detecta si la salida grep
es un archivo, una terminal, una tubería o lo que sea y actúa en consecuencia:
$ 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
Compara lo anterior con
$ echo foo | grep --color o >outfile; grep m outfile
$ echo foo | grep --color o | grep m
$
Entonces, usar la auto
opción básicamente solo imprimirá los colores cuando puedas verlos. Es realmente muy inteligente y funciona a las mil maravillas. Tanto es así que tengo:
$ type grep
grep is aliased to `grep --color'
Respuesta2
Por si sirve de algo, esta es exactamente la razón por la que --color
el valor predeterminado es --color=auto
y no --color=always
.
Si su objetivo es "Muéstrame todas las líneas que contienen A
y m
resaltan las coincidencias A
y m
los caracteres", parece que la solución más simple sería resaltar todo después de todas las coincidencias, usando un egrep para agregar el resaltado nuevamente. Algo como:
{
echo "A b";
echo "A m";
echo "B m";
echo "Another m";
} | grep 'A' | grep 'm' | egrep --color 'A|m';
Respuesta3
¿Cuál es el caso de uso real? Si desea codificar con colores A
todas las líneas que también contienen, m
simplemente puede invertir la grep
s:
echo A B C | grep m | grep --color=always A
Alternativamente, si está buscando un literal m
en la salida original, deberá excluir todos los códigos de color antes, grep m
pero imprimir el resultado.conlos códigos de colores. Una forma de hacer esto es usar nl
para numerar las líneas de la salida, grep
para un número de línea seguido de m
, guardar solo los números de línea de esa salida y luego usar sed -n
para imprimir solo las líneas en la salida codificada por colores.