web-dev-qa-db-fra.com

Mettez en surbrillance le texte similaire à grep, mais ne filtrez pas le texte

Lors de l'utilisation de grep, tout texte d'une ligne correspondant à votre expression régulière sera mis en surbrillance.

Que se passe-t-il si je souhaite ce comportement, mais que grep imprime également toutes les lignes? Je suis arrivé vide après un coup d'œil rapide dans la page de manuel de grep.

239
Martin Konecny

Utilisez ack. Vérifiez son option --passthru ici: ack . Il présente l'avantage supplémentaire de permettre l'utilisation d'expressions régulières Perl complètes.

$ ack --passthru 'pattern1' file_name

$ command_here | ack --passthru 'pattern1'

Vous pouvez aussi le faire en utilisant grep comme ceci:

$ grep --color -E '^|pattern1|pattern2' file_name

$ command_here | grep --color -E '^|pattern1|pattern2'

Cela correspondra à toutes les lignes et mettra en évidence les motifs. Le ^ correspond à chaque début de ligne, mais ne sera pas imprimé/mis en surbrillance car ce n'est pas un caractère.

(Notez que la plupart des configurations utilisent --color par défaut. Vous n’avez peut-être pas besoin de cet indicateur).

241
holygeek

Vous pouvez vous assurer que toutes les lignes correspondent mais il n'y a rien à mettre en évidence sur les correspondances non pertinentes

egrep --color 'Apple|' test.txt 

Notes:

  • egrep peut être orthographié aussi grep -E
  • --color est généralement utilisé par défaut dans la plupart des distributions
  • certaines variantes de grep "optimiseront" la correspondance vide, vous pouvez donc utiliser plutôt "Apple | $" (voir: https://stackoverflow.com/a/13979036/939457 )
89
Sorin

EDIT:

Cela fonctionne avec le grep de OS X Mountain Lion:

grep --color -E 'pattern1|pattern2|$'

C'est mieux que '^|pattern1|pattern2' parce que la partie ^ de l'alternance correspond au début de la ligne alors que $ correspond à la fin de la ligne. Certains moteurs d’expression régulière ne souligneront pas pattern1 ou pattern2 parce que ^ est déjà apparié et que le moteur est impatient .

Quelque chose de similaire se produit pour 'pattern1|pattern2|' parce que le moteur des expressions rationnelles remarque que l'alternance vide à la fin de la chaîne de modèle correspond au début de la chaîne de sujet.

[1]: http://www.regular-expressions.info/engine.html

FIRST EDIT:

J'ai fini par utiliser Perl:

Perl -pe 's:pattern:\033[31;1m$&\033[30;0m:g'

Cela suppose que vous avez un terminal compatible ANSI.

RÉPONSE ORIGINALE:

Si vous êtes coincé avec un grep étrange, cela pourrait fonctionner:

grep -E --color=always -A500 -B500 'pattern1|pattern2' | grep -v '^--'

Ajustez les chiffres pour obtenir toutes les lignes souhaitées.

La seconde grep supprime simplement les lignes -- superflues insérées par le style BSD grep sur Mac OS X Mountain Lion, même lorsque le contexte de correspondances consécutives se chevauche.

Je pensais que GNU grep avait omis les lignes -- lorsque le contexte se chevauchait, mais cela fait un moment que je me souviens peut-être mal.

32
willkil

Vous pouvez utiliser mon script mettre en évidence à partir de https://github.com/kepkin/dev-Shell-essentials

C'est meilleur que grep car vous pouvez mettre en surbrillance chaque correspondance avec sa propre couleur .

$ command_here | highlight green "input" | highlight red "output"

enter image description here

27
kepkin

Puisque vous voulez que les correspondances soient mises en évidence, c'est probablement pour la consommation humaine (par opposition à la canalisation vers un autre programme, par exemple), donc une solution intéressante serait d'utiliser:

less -p <your-pattern> <your-file>

Et si vous ne vous souciez pas de la sensibilité à la casse:

less -i -p <your-pattern> <your-file>

Cela a aussi l’avantage d’avoir des pages, ce qui est bien quand on doit passer par une longue sortie

15
acros

Vous pouvez le faire en utilisant seulement grep en:

  1. lire le fichier ligne par ligne
  2. correspondance d'un motif dans chaque ligne et mise en évidence du motif par grep
  3. s'il n'y a pas de correspondance, renvoie la ligne telle quelle

ce qui vous donne le suivant:

while read line ; do (echo $line | grep PATTERN) || echo $line  ; done < inputfile
4
jackhab

Si vous souhaitez imprimer "toutes" les lignes, il existe une solution simple:

grep "test" -A 9999999 -B 9999999
  • A => Après
  • B => Avant
2
Leon X. W.

Si vous faites cela parce que vous voulez plus de contexte dans votre recherche, vous pouvez le faire:

cat BIG_FILE.txt | less

Faire une recherche dans less devrait mettre en évidence vos termes de recherche.

Ou dirigez la sortie vers votre éditeur préféré. n exemple :

cat BIG_FILE.txt | vim -

Puis recherchez/mettez en surbrillance/remplacez.

0
dgo.a