web-dev-qa-db-fra.com

Sortie Grep avec plusieurs couleurs?

Existe-t-il une méthode élégante en bash pour exécuter grep sur un fichier texte avec deux motifs ou plus, et chaque motif qui correspond est affiché dans une couleur différente?

Donc, une ligne qui correspond à MALE et AUGUST afficherait MALE en bleu et AUGUST en orange? Je suis ouvert à l'utilisation de sed, awk, grep et des crayons ou autres.

47
Evil Genius

Vous pouvez mettre en cascade des greps de différentes couleurs en spécifiant --color = always et en utilisant l'expression régulière 'foo | $' pour passer toutes les lignes.

Par exemple:

tail -f myfwlog | GREP_COLOR='01;36' egrep --color=always 'ssh|$' | GREP_COLOR='01;31' egrep -i --color=always 'drop|deny|$'

Si vous souhaitez que la ligne entière soit mise en surbrillance, mettez à jour votre expression régulière en conséquence:

.... GREP_COLOR='01;31' egrep -i --color=always '^.*drop.*$|^.*deny.*$|$'
50
Rob Windsor

grep est un correcteur d'expressions régulières, pas un surligneur de syntaxe :). Vous devrez utiliser plusieurs invocations de grep, en utilisant une valeur différente de GREP_COLOR pour chaque.

GREP_COLOR="1;32" grep foo file.txt | GREP_COLOR="1;36" grep bar

Cela mettrait en évidence "foo" et "bar" de différentes couleurs dans des lignes qui correspondent aux deux. Je ne pense pas qu'il existe un moyen (simple) de gérer tous les occurrences de l'un ou l'autre modèle, à moins de fusionner le flux de sortie de deux appels indépendants:

{ GREP_COLOR="1;32" grep foo file.txt
  GREP_COLOR="1;36" grep bar file.txt
} | ...

qui sera évidemment différent que s'il y avait un moyen d'attribuer une couleur distincte à chaque expression régulière.


Vous pouvez utiliser awk pour remplacer chaque correspondance par elle-même enveloppée dans le code de contrôle correct.

 echo "foo bar" | awk '{ gsub("bar", "\033[1;33m&\033[0m");
                         gsub("foo", "\033[1;36m&\033[0m"); print }'

Dans chaque ligne, vous remplacez globalement tout ce qui correspond à l'expression régulière donnée par lui-même (&) enveloppé dans les séquences d'échappement ANSI pour la couleur souhaitée (qui grep --color fait pour vous). Après avoir traité toutes les correspondances possibles, vous devez imprimer explicitement la ligne.

29
chepner

Si vous voulez quelque chose hors de la boîte, vous cherchez probablement hhighlighter .

Voici un exemple:JBoss output

Regarde. C'est incroyablement utile pour colorer automatiquement des mots de différentes couleurs. C'est un projet impressionnant qui est construit sur ack .

15
Ehtesh Choudhury

J'avais besoin de mettre des chaînes en surbrillance dans les fichiers texte et je n'ai pas trouvé de moyen qui correspondait à mes besoins, j'ai donc écrit un programme C simple pour coloriser les chaînes correspondant aux expressions régulières.

Vous pouvez télécharger le code source depuis GitHub:

git clone http://github.com/mbornet-hl/hl

puis :

cd hl/cr; make

Voici l'utilisation:

hl: version 1.21
Usage: hl [-h|-eidD][-E][-rgybmcwRGYBMCW] regexp ...
  -h : help
  -v : version
  -u : do not bufferize output on stdout
  -e : extended regular expressions
  -i : ignore case
  -E : print on stderr
  -r : red
  -g : green
  -y : yellow
  -b : blue
  -m : Magenta
  -c : cyan
  -w : white
  -R : red     (reverse video)
  -G : green   (reverse video)
  -Y : yellow  (reverse video)
  -B : blue    (reverse video)
  -M : Magenta (reverse video)
  -C : cyan    (reverse video)
  -W : white   (reverse video)
  -d : debug
  -D : display regular expressions

Pour coloriser le mot "rouge" en rouge et le mot "bleu" en bleu, il suffit de taper la commande suivante:

echo "red blue red blue" | hl -r red -b blue

et voici un exemple pour mettre en évidence la sortie de la commande ifconfig:

hl -ei -m '^(eth|(vir)?br|vnet)[0-9.]*:[0-9]+\>'             \
       -b '^(eth|(vir)?br|vnet)[0-9.]*\.[0-9]+\>'            \
       -c '([0-9a-f]{2}:){5}[0-9a-f]{2}'                     \
       -g '\<UP\>|\<RUNNING\>|([0-9]{1,3}\.){3}[0-9]{1,3}\>' \
       -y '^(eth|(vir)?br|vnet)[0-9.:]*\>'                   \
       -W '[0-9a-f]{4}::[0-9a-f]{4}\:[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}' \
       -r ' (errors|dropped|overruns):[^0][0-9]*'

L'ordre dans lequel vous spécifiez les couleurs est important: si une chaîne correspond à plusieurs expressions régulières, la 1ère avec une priorité plus élevée que la 2ème, la 2ème avec une priorité plus élevée que la 3ème, et ainsi de suite ...

J'espère que cela t'aides.

8
Bush

Essayez le merveilleux rpen http://github.com/rtulke/rpen

require egrep or grep

Vous devez maintenant copier le fichier rpen.py dans le bon dossier et lui accorder les droits appropriés

cp rpen.py /usr/local/bin/rpen
chmod 777 /usr/local/bin/rpen

alors essaye

ps xau |rpen Ss "S\+" "\?\?" 
3
cray

Voici donc la ou les versions utilisant sed. Disons que vous voulez que le mot "FAILED" soit coloré en rouge, ce serait:

sed 's/\(ERROR\)/\o033[31m\1\o033[39m/'

Pour que la ligne entière contenant le mot "FAILED" soit marquée en rouge:

sed 's/\(.*ERROR.*\)/\o033[31m\1\o033[39m/'

Pour que plusieurs mots soient marqués en rouge:

sed 's/\(ERROR\|FAILED\)/\o033[31m\1\o033[39m/'

Pour avoir plusieurs mots et leurs lignes wohle marquées en rouge:

sed 's/\(.*FAILED.*\|.*ERROR.*\)/\o033[31m\1\o033[39m/'

Pour avoir plusieurs couleurs (ERREUR = rouge/ECHEC = bleu)

sed -e 's/\(ERROR\)/\o033[31m\1\o033[39m/' -e 's/\(FAILED\)/\o033[34m\1\o033[39m/'

Pour utiliser tout cela sur ssh:

ssh user@Host -t "tail -n 1024 -f /some/log/file | sed --unbuffered -e 's/\(.*ERROR.*\|.*FAILED.*\)/\o033[31m\1\o033[39m/' -e 's/\(.*postfix.*\|.*dhcpd.*\)/\o033[32m\1\o033[39m/'"

Et pour ne pas avoir à taper ceci à chaque fois, déclarez-le simplement comme une fonction dans votre bashrc.

Pour d'autres couleurs, recherchez les codes ANSI.

2
mikeymouse

Que dis-tu de ça? Vous pouvez le faire avec grep UNIQUEMENT! Les astuces ici sont (1) vous prenez/OU/des mots que vous recherchez; (2) vous utilisez les options -A et -B avec un nombre suffisamment grand (plus grand que le nombre de lignes de votre fichier).

echo "you make it" > tmp
echo "you take it" >> tmp
echo "you cake it" >> tmp
echo "you bake it" >> tmp
echo "you wake it" >> tmp

GREP_COLOR='1;32' grep -P "(take|cake|bake)" --color=always tmp | GREP_COLOR='1;33' grep -P "(cake|bake)" --color=always -A10000 -B10000 | GREP_COLOR='1;34' grep -P "(bake)" --color=always -A10000 -B10000 
1
user22097

Ma réponse est ci-dessous:

tailf logfile awk '/MALE/' {print "\033[34m" $0 "\033[39m"}  '/MALE/' {print "\033[33m" $0 "\033[39m"}
1
Ramin Ismayilli

cxpgrep est juste à cet effet - mettez en surbrillance des motifs de différentes couleurs.

cxpgrep 'PAT1|PAT2|...' FILE_OR_DIRECTORY
1
treulz