Convaincre grep de sortir toutes les lignes, pas seulement celles avec des allumettes

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 

Capture d'écran des deux commandes

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" "$@" }