Disons que j'ai le file suivant:
$ cat test test line 1 test line 2 line without the search word another line without it test line 3 with two test words test line 4
Par défaut, grep
renvoie chaque ligne contenant le terme de search
$ grep test test test line 1 test line 2 test line 3 with two test words test line 4
Si vous passez grep
--color
, la partie de la ligne qui correspond à l'expression de search est affichée, mais elle ne renvoie que les lignes contenant l'expression. Existe-t-il un moyen d'get grep
pour sortir chaque ligne du file source, mais mettre en évidence les correspondances?
Mon hack terrible actuel pour accomplir ceci (au less sur les dossiers qui n'ont pas 10000+ lignes consécutives sans les allumettes) est:
$ grep -B 9999 -A 9999 test test
Si grep
ne peut pas accomplir cela, existe-t-il un autre outil de command line qui offre la même fonctionnalité? J'ai joué avec ack
, mais il ne semble pas avoir une option pour cela soit
grep --color -E "test|$" yourfile
Ce que nous faisons ici correspond au model $
et au model de test, évidemment $
n'a rien à colorier, donc seulement le motif de test obtient de la couleur. Le -E
allume simplement la correspondance regex étendue.
Vous pouvez créer facilement une fonction comme ceci:
highlight () { grep --color -E "$1|$" "${@:1}" ; }
ack --passthru --color ssortingng file
pour Ubuntu et Debian, utilisez ack-grep au lieu d'ack
ack-grep --passthru --color ssortingng file
J'ai la fonction suivante que j'utilise pour de telles choses:
highlight () { perl -pe "s/$1/\e[1;31;43m$&\e[0m/g" }
En interne, il semble un peu moche, c'est sympa et facile à utiliser, comme ça:
cat some_file.txt | highlight some_word
ou, pour un exemple un peu plus réel:
tail -f console.log | highlight ERROR
Vous pouvez changer les colors à tout ce que vous voulez (ce qui pourrait être difficile avec grep – je ne suis pas sûr) en changeant les 1
et 31
et 43
(après \e[
) à des valeurs différentes. Les codes à utiliser sont partout , mais voici une intro rapide: le 1 plie le text, le 31
rend rouge, et le 43
donne un fond jaune. 32
ou 33
seraient de différentes colors, et 44
ou 45
seraient des fonds différents: vous avez l'idée. Vous pouvez même faire clignoter (avec un 5
) si vous êtes si enclin.
Cela n'utilise aucun module Perl spécial, et Perl est presque omniprésent, donc je m'attendrais à ce qu'il fonctionne à peu près n'importe où. La solution grep est très intelligente, mais le commutateur –color de grep n'est pas disponible partout. Par exemple, je viens d'essayer cette solution sur une boîte Solaris exécutant bash, et un autre exécutant ksh, et ma machine Mac OS X locale exécutant zsh. Tout a bien fonctionné. Solaris s'est étouffé sur la solution grep --color
, cependant.
Aussi, ack est génial, et je le recommand à tous ceux qui ne l'ont pas encore découvert, mais j'ai eu quelques problèmes pour l'installer sur quelques-uns des nombreux servers sur lesquels je travaille. (J'oublie pourquoi: je pense que lié aux modules Perl cela a exigé.)
Puisque je ne pense pas avoir déjà travaillé sur un Unix qui n'a pas installé Perl (à l'exception des systèmes embarqués, des routeurs Linksys, etc.), je dirais que c'est une solution universellement utilisable .
Une autre façon de le faire correctement et de façon portative avec grep
(en plus d'utiliser deux expressions rationnelles avec l'alternance comme dans la réponse acceptée) est via le motif nul (et respectivement la string nulle).
Il devrait fonctionner aussi bien avec les deux commutateurs -E
et -F
puisque, selon la norme :
-E Match using extended regular expressions. [...] A null ERE shall match every line.
et
-F Match using fixed ssortingngs. [...] A null ssortingng shall match every line.
Donc c'est juste une question de courir
grep -E -e '' -e 'pattern' infile
et respectivement
grep -F -e '' -e 'ssortingng' infile
Tu peux essayer:
perl -MTERM::ANSIColor -nle '/pattern/ ? print colored($_, 'color') : print' test
Pas très portable cependant, et même si Perl est installé, vous devrez peut-être download un autre module. En outre, il va colorer toute la ligne, pas seulement le mot recherché.
Il y a un moyen beaucoup plus facile de le faire pour GNU grep mais je ne pense pas que ce soit portable (ie, grep BSD):
Dans un tuyau:
cat <file> | grep --color=always -z <query>
Sur un file:
grep --color=always -z <query> <file>
Le crédit va à la réponse de Cyrus ici .
Une version sed
, fonctionne à la fois bash
et ash
.
#highlight hsed(){ local pattern="$1" shift local r=`echo -e '\e'[31m` local c=`echo -e '\e'[0m` sed "s:${pattern//:/\:}:$r\0$c:g" "$@" }