Me preguntaba si hay un programa en el conjunto de herramientas comunes de Unix, como grep, que en lugar de filtrar las líneas que contienen una cadena, simplemente genera la misma entrada pero resalta o colorea la cadena seleccionada.
Estaba pensando en hacerlo yo mismo (debería ser lo suficientemente simple), pero tal vez ya existe como un comando de Unix.
Estoy planeando usarlo para monitorear registros, así que haría algo como esto:
tail -f logfile.log | highlight "error"
Por lo general, cuando estoy monitoreando registros, necesito encontrar una cadena en particular, pero también necesito saber qué está escrito antes y después de la cadena, por lo que filtrar a veces no es suficiente.
Algo como eso existe?
Gracias
Este es un truco divertido para ello con el grep
comando básico. Consiste en utilizar dos filtros: el que desea aplicar y uno ficticio que iguala todas las líneas pero no produce ningún resaltado. Esta coincidencia ficticia puede ser ^
(comienzo de línea) o $
(final de línea).
grep "^\|text" --color='always' file
o
grep -E "^|text" --color='always' file
Vea un ejemplo:
$ cat a
hello this is
some text i wanted
to share with you
$ grep "^\|text" --color='always' a
hello this is
some text i wanted # "text" is highlighted
to share with you
^
o $
y simplemente "|text"
funciona también.Hay una herramienta llamada ack
. Puede encontrarlo en http://beyondgrep.com y, de hecho, es una herramienta más allá de grep. Su uso más común es el relleno de ese papel find . -name "*.java" --print | xargs grep clazz
o similar. Porque hacemos eso todo el tiempo.
Solo ack clazz
y obtienes la salida. Busca los archivos adecuados (no se molesta en tratar de grep binarios) y también ofrece una buena salida de color.
Si lo usa con la --passthru
opción, imprimirá todo el flujo de entrada, resaltando las regiones coincidentes en color.
--passthru
Imprimir todas las líneas, ya sea que coincidan o no
Como indica la documentación, si -
se usa para el archivo, se necesitará STDIN:
Si se especifican archivos o directorios, solo se comprueban esos archivos y directorios. ack también puede buscar STDIN, pero solo si no se especifica ningún argumento de archivo o directorio, o si uno de ellos es "-".
Por lo tanto, perdone el cat
abuso ( y el juego de palabras, vea a continuación ), puede tenerlo:
$ cat file | ack --passthru pattern
$ cat file | ack --passthru pattern -
Esto tomará la salida de la tubería y la enviará a través de ack
la cual imprimirá todas las líneas (con --passthru
) con el patrón resaltado.
Esta es exactamente la herramienta que está buscando (y un poco más). Es un paquete estándar para muchos administradores de paquetes. Consulte http://beyondgrep.com/install/ para conocer su favorito.
_ /| \'oO' =(___)= ¡Cuidado, thpppt!
(Si no lo reconoce, ese es Bill the Cat , aunque la búsqueda de imágenes también podría ayudar, no haga clic en el conjunto de Miley Cyrus)
grep -R
, como explica, no veo cómo puede ayudar al OP.--passthru
opción imprimirá todas las líneas y resaltará los patrones de interés. Del mismo modo, para trabajar en STDIN, se puede usar el guión como el 'nombre' del archivo, o ningún argumento de archivo.Puede usar la grep -C
bandera que da n líneas de contexto, por ejemplo grep -C 3
, imprimirá las 3 líneas antes y después del partido. Los hay también -B
y -A
para antes y después.
Si está buscando resaltar cadenas dadas regularmente, por ejemplo, formatos de registro específicos, podría valer la pena usar python pygmentize con un lexer personalizado , ya que está basado en expresiones regulares, se sorprenderá de lo fácil que es . Este último también tiene la ventaja de ser multiplataforma aunque algunos terminales no funcionan muy bien con el color.
Soy fan de hhighlighter de Paolo Antinori. https://github.com/paoloantinori/hhighlighter
Un lado positivo de este comando es que puede resaltar hasta 10 palabras con colores únicos. Simplemente canalice la salida de un comando h
con las palabras para resaltar.
Por ejemplo tail -f /var/log/somelog.log | h "ERROR"
, producirá:
He escrito un pequeño script que coloreará cualquier cadena que le des:
#!/usr/bin/env perl
use Getopt::Std;
use strict;
use Term::ANSIColor;
my %opts;
getopts('hic:l:',\%opts);
if ($opts{h}){
print<<EoF;
Use -l to specify the pattern(s) to highlight. To specify more than one
pattern use commas.
-l : A Perl regular expression to be colored. Multiple expressions can be
passed as comma separated values: -l foo,bar,baz
-i : makes the search case sensitive
-c : comma separated list of colors;
EoF
exit(0);
}
my $case_sensitive=$opts{i}||undef;
my @color=('bold red','bold blue', 'bold yellow', 'bold green',
'bold magenta', 'bold cyan', 'yellow on_magenta',
'bright_white on_red', 'bright_yellow on_red', 'white on_black');
if ($opts{c}) {
@color=split(/,/,$opts{c});
}
my @patterns;
if($opts{l}){
@patterns=split(/,/,$opts{l});
}
else{
$patterns[0]='\*';
}
# Setting $| to non-zero forces a flush right away and after
# every write or print on the currently selected output channel.
$|=1;
while (my $line=<>)
{
for (my $c=0; $c<=$#patterns; $c++){
if($case_sensitive){
if($line=~/$patterns[$c]/){
$line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ge;
}
}
else{
if($line=~/$patterns[$c]/i){
$line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ige;
}
}
}
print STDOUT $line;
}
Si lo guarda como color
en un directorio que está en su $PATH
y lo hace ejecutable ( chmod +x /usr/bin/color
), puede colorear el patrón coincidente de esta manera:
echo -e "foo\nbar\nbaz\nbib" | color -l foo,bib
Eso producirá:
Tal como está escrito, el script tiene colores predefinidos para 10 patrones diferentes, por lo que darle una lista separada por comas como en el ejemplo anterior coloreará cada uno de los patrones combinados en un color diferente.
Escribí un programa para hacer esto hace algún tiempo. Lo llamo cgrep (por color grep).
Puede descargarlo copiando la sección del código desde aquí en un archivo vacío: http://wiki.tcl.tk/38096
Luego haga que el archivo sea ejecutable y cópielo en uno de sus directorios bin regulares.
Está escrito en tcl, por lo que necesita tcl instalado (8.5 y superior). Pero la mayoría de las distribuciones de Linux tendrían tcl instalado de todos modos, ya que muchos programas lo usan (gitk, kernel config, expect, etc.).
La sintaxis para colorear es simple: regex option option ..
. Puede tener tantas expresiones regulares como desee. Aquí hay un ejemplo que colorearía los errores en rojo y las advertencias en amarillo:
tail -f logfile | cgrep '^.*WARNING.*$' -fg yellow '^.*ERROR.*$' -fg red -bg yellow
Bueno, estoy ejecutando Fedora 21 y si escribo
grep -E \|kk rs.c
generará todo el contenido del archivo "rs.c" mientras resalta cualquier aparición de "kk".
Puedes usar este comando
grep --color --context=1000
o más corto
grep --col -1000
Un truco simple es hacer coincidir también una cadena vacía o el comienzo de una línea; cualquiera da como resultado una coincidencia de longitud cero para todas las líneas:
grep --color -e 'REGEXP' -e ''
grep --color -e 'REGEXP' -e ^
O (sintaxis extendida de expresiones regulares):
grep --color -E 'REGEXP|'
egrep --color 'REGEXP|'
REGEX
también la salida? Acabo de probar, y lo hace. Entonces eso no coincide con los requisitos (solo resaltar, no filtrar). Pero la segunda variante de hecho hace lo que solicitó el OP (verificado;).REGEX
(resalta ese término) y para "nada" (que es "en todas partes"). ¿Puedo sugerirle que incluya esta pequeña explicación (también aclare lo que hace), y luego eliminemos nuestros comentarios (para limpieza)? ¡Gracias! Mientras tanto +1 de mí :)uso less
_ La cadena de búsqueda encontrada por /
es una expresión regular y las ocurrencias se resaltarán.
En mi .bashrc tengo esta función. Lo llamo cgrep
, pero le estoy dando un nombre un poco más apropiado aquí.
highlight() { grep -E --color "^|$1"; }
Encuentro esto útil para registros de seguimiento, por ejemplo, donde quiero resaltar una palabra clave pero veo todo lo que sucede.
tail -f /var/log/SOMELOG | highlight KEYWORD
Simplemente puede canalizar su salida a:
sed "s/\([Ee][Rr][Rr][Oo][Rr]\)/`tput rev`\1`tput rmso`/"
Aquí estoy usando una expresión regular que coincidirá con "error", "ERROR", "ErRoR", etc. en las 32 variaciones posibles.
Tengo la siguiente función definida en mi ~/.zshrc
:
hl () {
sed s/$1/$'\e[1;31m'\&$'\e[0;m'/
}
Úsalo con tail -f logfile.log | hl "error"
. Agrega una secuencia de escape para Light Red antes de la palabra resaltada y restablece sin color después de la palabra. Puede encontrar otros códigos de color aquí: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
martino dino
Mawg dice que reincorpore a Monica