2008-10-27 9 views
19

Al utilizar grep --color=always puedo obtener un bonito resaltado de color para las coincidencias de expresiones regulares.coincidencias de color con regularidad - sin omitir omisiones

Sin embargo, grep solo devuelve líneas con al menos una coincidencia. En su lugar, estoy buscando una manera de simplemente resaltar las coincidencias de expresiones regulares, dejando todas las otras entradas por sí solas, sin dejar líneas sin ninguna coincidencia.

He intentado obtener color trabajando con sed, y he leído la documentación de grep, pero parece que no puedo obtener lo que quiero.

En el caso de la descripción de mi isnt obvio, quiero:

ENTRADA:

  • Fred
  • Ted
  • roja
  • llevan

Regex:

SALIDA "* rojo.":

  • Fred (en rojo)
  • Ted
  • roja (en rojo)
  • llevan

Para que yo pudiera hacer:

list_stuff | color_grep "make_this_stand_out_but_dont_hide_the_rest" 

EDIT:

he encontrado una solución, que no es bonito, pero funciona:

Gracias a: http://www.pixelbeat.org/docs/terminal_colours/

Particularmente el guión (que he modificado/simplificado): http://www.pixelbeat.org/talks/iitui/sedgrep

function sedgrep() 
{ 
    C_PATT=`echo -e '\033[33;01m'` 
    C_NORM=`echo -e '\033[m'` 

    sed -s "s/$1/${C_PATT}&${C_NORM}/gi" 
} 

¡Todavía estoy buscando una forma más fácil de hacerlo!

Respuesta

3

Esta pequeña función funciona bien en mi ZShell:

function color_grep { 
    sed s/$1/$fg[yellow]$1$terminfo[sgr0]/g 
} 

(Necesidades

autoload colors zsh/terminfo 

)

Tal vez se puede hacer algo similar?

Editar: Lo sentimos, esto no funcionará con los regexes. Tendrás que modificarlo un poco ...

+0

Estoy usando bash, pero parece ser casi el mismo tipo de solución que el que publiqué. ¡Gracias! – mmocny

1

La forma en que estás haciendo esto ahora es probablemente tan limpia como puedes esperar, a menos que, por supuesto, escribas tu propia herramienta grep. Si usted no necesariamente se preocupan por preservar el orden de la salida, aquí está la otra manera que puedo pensar para hacer esto:

function colormatch() 
{ 
    tee - | grep --color=always $1 | sort | uniq 
} 

no tan eficiente como usando sed (más procesos creados, y tee-ing la salida), así que probablemente recomendaría seguir con su solución sed.

+0

Buen punto. Su solución tiene una sintaxis que es más fácil de recordar, para aquellos momentos en que no tengo mi archivo .bashrc útil :) – mmocny

2

Puede usar la opción -C<num> para grep que le muestra <num> líneas de contexto alrededor de su coincidencia. Solo asegúrese de que <num> sea tan grande como el número de líneas en su archivo.

+0

oooh, abuso inteligente de la opción de contexto, me gusta :-) – Jay

+1

En realidad, yo probamos este, y no funcionó por tres razones: Una, si no fuera una coincidencia, no devolvería nada. Dos, fue lento cuando era realmente grande. Tres (mayor problema), los resultados se imprimen con cada "partido", por lo que si estoy ejecutando este comando en un tubo que obtener una salida de gotas – mmocny

+0

Sin embargo, es una manera muy inteligente de hacerlo como un corte rápido, especialmente para pequeños resultados si se sabe que su sea un éxito :) hago esto todo el tiempo cuando no en mi propio PC – mmocny

0

Hace poco hice algo similar como filtro. Lo uso para colorear los "encabezados" en una cola con varios archivos, como este:

tail -f access.log error.log foo.log | logcol.sh

Los encabezados de este aspecto:

==> access.log < ==

que se confundió por los cambios rápidos entre los diferentes archivos de registro, por lo que este logcol.sh ayuda. El ==> está codificado para el uso específico pero también podría ser un parámetro.

#!/bin/sh 
while read line 
do 
    if test `expr "$line" : "==>.*"` -eq 0 ; 
    then 
    printf '\033[0m%s\n' "$line" 
    else 
    printf '\033[0;31m%s\n' "$line" 
    fi 
done 

Quizás no sea el más elegante, pero creo que es bastante legible. espero que no tengo ninguna errata ;-) HTH, robar

20

La solución más simple sería utilizar egrep --color=always 'text|^' que coincida con todos los comienzos de línea, pero sólo el color del texto deseado.

+3

esto no funcionó para mí, pero esto: egrep -color = siempre 'texto | $' soy usando zsh por cierto. – Tony

7

Aquí hay un script que uso para colorear el resultado.

Creo que encontré la idea/snippet en algún tipo de blog o tutorial de bash/sed - no puedo encontrarlo más, fue hace mucho tiempo.

#!/bin/bash 

red=$(tput bold;tput setaf 1)    
green=$(tput setaf 2)      
yellow=$(tput bold;tput setaf 3)   
fawn=$(tput setaf 3) 
blue=$(tput bold;tput setaf 4)   
purple=$(tput setaf 5) 
pink=$(tput bold;tput setaf 5)   
cyan=$(tput bold;tput setaf 6)   
gray=$(tput setaf 7)      
white=$(tput bold;tput setaf 7)   
normal=$(tput sgr0)      

sep=`echo -e '\001'` # use \001 as a separator instead of '/' 

while [ -n "$1" ] ; do 
    color=${!1} 
    pattern="$2" 
    shift 2 

    rules="$rules;s$sep\($pattern\)$sep$color\1$normal${sep}g" 
done 

#stdbuf -o0 -i0 sed -u -e "$rules" 
sed -u -e "$rules" 

Uso:

./colorize.sh color1 pattern1 color2 pattern2 ... 

por ejemplo

dmesg | colorize.sh red '.*Hardware Error.*' red 'CPU[0-9]*: Core temperature above threshold' \ 
green 'wlan.: authenticated.*' yellow 'wlan.: deauthenticated.*' 

No funciona bien con patrones superpuestos, pero de todos modos lo he encontrado muy útil.

HTH

Cuestiones relacionadas