grep: ¿cómo colorear 2 palabras clave?

12

Sé cómo agrupar 2 palabras clave con 1 comando, pero solo puedo colorear una de ellas en la salida. Aquí está mi comando:

grep 'keyword1' file.log | grep 'keyword2'

Solo keyword2está resaltado. ¿Cómo puedo keyword1resaltar al mismo tiempo?

Rapaz
fuente

Respuestas:

15

El grepcomando acepta una --color=alwaysopción, por lo que puede usar

grep 'keyword1' file.log --color=always | grep 'keyword2'

Como señala gertvdijk , este comando puede ser ineficiente, pero buscará todas las líneas que contengan palabra clave1 y palabra clave2. Si desea resaltarlos en diferentes colores, puede usar

grep 'keyword1' file.log --color=always | GREP_COLORS="mt=01;34" grep --color=always 'keyword2'

que resaltará la palabra clave2 en azul. La mtparte significa que grepresaltará el texto coincidente utilizando este código CSI y 01;34significa "primer plano azul en negrita sobre fondo normal".

Daniel H
fuente
1
¡+1 para obtener una explicación detallada y opciones de personalización para el caso de uso!
gertvdijk
Es curioso, cuando intento esto con: grep -R --color = always keyword1. El | grep keyword2 // solo se resalta la primera palabra clave. ¿Cómo podría adaptar su respuesta para trabajar con la búsqueda recursiva?
TenLeftFingers
1
Eso es extraño, grep -R --color=always keyword1 . | grep keyword2debería funcionar. ¿Está redirigiendo la salida nuevamente (por ejemplo, colocando el segundo grepen less -R)? Si es así, también deberá agregar --color=alwaysal segundo.
Daniel H
¡Gran respuesta! Para resaltar ambos, --color=autosería necesario un segundo grep, justo después 'keyword2'.
Luis
@Luis Sí, tienes razón en que Grep por lo general por lo general no tiene color (aunque ¿podría ser una opción de configuración de tiempo? No creo que haya anulado eso en 2013 cuando funcionó en mi máquina sin eso ...). Agregué --color=alwaysa la respuesta, porque es posible que desee canalizarlo lesso algo también.
Daniel H
3

Pruebe expresiones regulares reales, en lugar de canalizar a otra instancia de grep, por ejemplo:

grep -E "\<foo\>.*\<bar\>" file

Esto limita a las líneas coincidentes en las que las palabras clave coinciden solo en este orden, lamentablemente. De todos modos, el uso de grepen su pregunta es bastante ineficiente y debe evitarlo. La respuesta de @DanielH es mucho más sencilla para su caso, probablemente.

Para una "o" coincidencia de palabras clave, uso esto regularmente:

grep -E "(foo|bar)" file
gertvdijk
fuente
1
Creo que el OP solo quiere líneas que contengan ambas palabras clave (el comando que proporcionó proporciona todas las líneas que contienen cualquiera de las dos).
Daniel H
@DanielH Gracias por señalar eso. He actualizado mi respuesta.
gertvdijk
¿Todavía no funciona eso si foo viene antes del bar? No sé si hay una mejor manera que foo.*bar|bar.*foo, o si eso es incluso necesario para este caso (que parece ser un archivo de registro que probablemente tendría un orden estándar para las palabras clave). Agregué mi respuesta antes de que actualizara la suya, pero la mantendré disponible en caso de que haya una situación en grepla que realmente sea necesario encadenar s (o en cualquier otro momento en que la salida en color no deba enviarse al terminal, como grep | less -R).
Daniel H