Introduction au grep et aux expressions régulières

Introduction au grep et aux expressions régulières

Objectif

Après avoir lu ce didacticiel, vous devriez être en mesure de comprendre comment fonctionne la commande grep et comment l'utiliser avec des expressions régulières de base et étendues.

Difficulté

FACILE

Introduction

Grep est l'un des outils les plus utiles que nous puissions utiliser lors de l'administration d'une machine basée sur Unix: son travail consiste à rechercher un modèle donné dans un ou plusieurs fichiers et retourner les correspondances existantes.

Dans ce tutoriel, nous verrons comment l'utiliser, et nous examinerons également ses variantes: faire un coup de pouce et fgrep. Nous mettrons cet extrait vraiment célèbre du livre «Le Seigneur des Anneaux» sur un fichier, et nous utiliserons comme cible pour nos exemples:

Trois anneaux pour les Elven-Kings sous le ciel, sept pour les nains dans leurs salles de pierre, neuf pour les mortels condamnés à mourir, un pour le Seigneur des Ténèbres sur son trône sombre au pays du Mordor où se trouve les ombres. Une bague pour les gouverner toutes, une bague pour les trouver, une bague pour les amener toutes, et dans l'obscurité les lier, dans le pays du Mordor où se trouvent les ombres. 

Le fichier sera appelé lotr.SMS.

Variantes Grep

Dans l'introduction, nous avons parlé de deux variantes Grep: faire un coup de pouce et fgrep. Ces variantes sont en fait obsolètes, car elles sont l'équivalent de l'exécution du grep avec le -E et -F Options respectivement. Avant de commencer à expliquer en quoi ces variantes sont différentes de l'original, nous devons examiner le comportement GREP par défaut lors de l'utilisation d'expressions régulières.

Le mode d'expression régulière de base

Une expression régulière est un modèle construit en suivant des règles spécifiques afin de faire correspondre une chaîne ou plusieurs chaînes. Par défaut, Grep utilise ce qu'il appelle Brillant ou des expressions régulières de base: dans ce mode, seuls certains méta-personnages (caractères ayant une signification particulière à l'intérieur d'une expression régulière) sont disponibles.

À titre d'exemple, nous essaierons d'utiliser Grep pour correspondre à une chaîne très simple, le mot «mortel». La syntaxe GREP est très simple: nous invoquons le programme fournissant le modèle à correspondre comme le premier argument, et le fichier cible comme le second:

$ grep mortel lotr.SMS


La commande ci-dessus ne renvoie aucune correspondance, bien que le mot «mortel» apparaît dans le texte: c'est parce que par défaut Grep effectue une recherche dans sensible aux majuscules et minuscules Mode, donc, puisque le mot «mortel» est capitalisé, il ne correspond pas au modèle que nous avons fourni. Pour surmonter ce problème et effectuer une recherche plus «générique», nous pouvons utiliser le -je Option (abréviation pour --ignorer les cas, ce qui fait que Grep ignore les distinctions de cas:

$ grep -i mortel lotr.SMS

Cette fois, la commande produit la sortie suivante (la correspondance réelle est mise en évidence en rouge):

Neuf pour les mortels condamnés à mourir,

Une chose importante à remarquer est que, par défaut, Grep renvoie toute la ligne dans laquelle le match est trouvé. Ce comportement, cependant, peut être modifié en utilisant le -o option, ou sa longue version --uniquement par correspondance. Lorsque vous utilisez cette option, seule le match lui-même est imprimé:

$ grep -o -i mortel lotr.mortel txt 

Un autre commutateur intéressant que nous pouvons utiliser est -n, court pour --numéro de ligne. Lorsque cette option est utilisée, le nombre de lignes où une correspondance est trouvée est incluse dans la sortie GREP. Cette commande:

$ grep -n -i mortel lotr.SMS

Produit la sortie suivante:

3: Neuf pour les mortels condamnés à mourir

3 est le nombre de la ligne dans laquelle le match est trouvé.

Et si nous voulons simplement obtenir le nombre réel de matchs trouvés, au lieu des matchs eux-mêmes? GREP a une option dédiée pour obtenir ce résultat: -c, ou --compter. L'utilisation de la commande ci-dessus avec cette option renvoie la sortie suivante:

1

Qui est, comme prévu, le nombre de correspondances trouvées dans le texte.

Méta-personnages de base

Il est temps d'effectuer une recherche un peu plus élaborée. Nous voulons maintenant trouver toutes les lignes en commençant par la lettre «O». Même lorsque nous travaillons avec des expressions régulières de base, nous pouvons utiliser le ^ Caractère pour correspondre à la chaîne vide au début d'une ligne:



$ grep -i ^ o lotr.SMS

Comme prévu, le résultat de la commande est:

Un pour le Seigneur des Ténèbres sur son trône sombre un anneau pour les gouverner tous, un anneau pour les trouver, une bague pour les amener toutes, et dans l'obscurité les lier, 

C'était assez facile. Supposons maintenant que nous voulons restreindre davantage notre recherche, et trouver toutes les lignes en commençant par un «O» et en terminant par un personnage «». Nous pouvons utiliser cet exemple pour introduire d'autres méta-personnages que nous pouvons utiliser en mode regex de base:

$ grep -i ^ o.*, $ lotr.SMS

La commande Linux ci-dessus renvoie exactement ce que nous recherchions:

 Une bague pour les gouverner toutes, une bague pour les trouver, une bague pour les amener toutes, et dans l'obscurité les lier,  

Expliquons ce que nous avons fait ci-dessus. Tout d'abord, nous avons utilisé le -je Option pour rendre notre recherche insensible à la recherche, tout comme nous l'avons fait dans les exemples précédents, que nous avons utilisé le ^ Meta-Character, suivi d'un «O», à la recherche de lignes en commençant par cette lettre.

Nous avons utilisé deux nouveaux méta-charcutiers: . et *. Quel est leur rôle dans l'expression régulière? Le . correspond à n'importe quel caractère unique, tandis que le * est un opérateur de répétition, qui correspond à l'élément précédent zéro ou plus de fois. Enfin, nous avons spécifié le ,, Une virgule, à égaler littéralement comme dernier personnage avant la fin de la ligne, s'assortit par le $ méta-personnage.

Correspondant à un ensemble de personnages avec des crochets

Dans l'exemple ci-dessus, nous avons utilisé le point, ., Pour spécifier un modèle qui correspond à chaque personnage. Et si nous voulions égaler seulement un sous-ensemble de caractères? Disons que, par exemple, nous voulions trouver toutes les lignes en commençant par un «O» ou un «i»: pour obtenir un tel résultat, nous pouvons enfermer l'ensemble des caractères possibles à égaler entre crochets:

$ grep -i ^ [o, i] lotr.SMS

La commande effectuera une recherche insensible à la casse d'un «O» ou d'un «i» situé au début d'une ligne. Voici le résultat:

Un pour le Seigneur des Ténèbres sur son trône sombre au pays du Mordor où se trouvent les ombres. Une bague pour les gouverner toutes, une bague pour les trouver, une bague pour les amener toutes, et dans l'obscurité les lier, dans le pays du Mordor où se trouvent les ombres. 


Pour que le motif soit apparié, comme il est ci-dessus, au moins un des personnages contenus avec des supports doit être trouvé. Lorsque vous spécifiez des caractères à l'intérieur des crochets, nous pouvons spécifier également un gamme en utilisant le - personnage. Ainsi, par exemple, pour faire correspondre les chiffres que nous pouvons écrire [0-9]. De retour à notre texte, nous pouvons utiliser cette syntaxe pour faire correspondre les lignes à partir des lettres de «i» à «s» (cas insensible):

$ grep -i ^ [i-s] lotr.SMS

La sortie de la commande:

Sept pour les nains de nains dans leurs salles de pierre, neuf pour les mortels condamnés à mourir, un pour le Seigneur des Ténèbres sur son trône sombre au pays du Mordor où se trouvent les ombres. Une bague pour les gouverner toutes, une bague pour les trouver, une bague pour les amener toutes, et dans l'obscurité les lier, dans le pays du Mordor où se trouvent les ombres. 

Ce qui précède est presque tout le texte du poème: seule la première ligne, qui commence par la lettre «T» (non incluse dans la gamme que nous avons spécifiée), a été exclue du match.

Dans les crochets, nous pouvons égaler également des classes de caractères spécifiques, en utilisant prédéfini expressions de support. Certains exemples sont:

  • [: alnum:] - caractères alphanumériques
  • [: chiffre:] - chiffres de 0 à 9
  • [: inférieur:] - lettres minuscules
  • [: supérieur:] - Lettres de case supérieur
  • [: Blank:] - Espaces et onglets

Celui ci-dessus n'est pas une liste complète, mais vous pouvez facilement trouver plus d'exemples d'expressions de support en consultant le manuel Grep.

Inverser le résultat d'un match

Dans les exemples ci-dessus, nous avons recherché chaque ligne en commençant par un «O» ou un «I», en utilisant une recherche insensible au cas. Et si nous voulions obtenir la sortie opposée, et donc pour ne trouver que des lignes sans correspondance?

Grep nous permet d'obtenir ce résultat en utilisant le -V Option (abréviation pour --correspondance inversée). L'option, comme suggéré, demande à Grep de renvoyer le match inversé. Si nous exécutons la dernière commande que nous avons utilisée ci-dessus pour fournir cette option, nous devons obtenir uniquement la première ligne du poème comme sortie. Vérifions-le:

$ grep -i -v ^ [i-s] lOTR.SMS

Le résultat est comme nous nous attendions à ce que nous nous attendions, seulement la première ligne du poème:

Trois anneaux pour les Elven-Kings sous le ciel,

Dans notre exemple, nous pouvons obtenir le même résultat en préfixant la liste des caractères entre les crochets avec le ^ caractère qui, dans ce contexte, assume une signification différente, ce qui fait correspondre le modèle à correspondre uniquement aux caractères non contenus dans la liste. Si nous courons:

$ grep -i ^ [^ i-s] lotr.SMS

Nous recevons, la même sortie qu'avant:

Trois anneaux pour les Elven-Kings sous le ciel,

Mode d'expression étendu

En utilisant faire un coup de pouce ou grep avec le -E Option (ce dernier est le moyen recommandé), nous pouvons accéder à d'autres méta-personnages à utiliser dans des expressions régulières. Voyons-les.



Opérateurs de répétitions avancées

Nous avons déjà rencontré le * L'opérateur de répétition qui est disponible également en mode d'expression régulière de base. Lorsque vous utilisez des expressions étendues, nous avons accès à d'autres opérateurs de ce type:

  • ? - correspond à l'article qui le précédent une ou zéro fois
  • + - correspond à l'élément précédent une ou plusieurs fois

Nous pouvons également spécifier plus de répétitions granulaires en utilisant une syntaxe de croyance. Par exemple, le modèle suivant correspond à chaque occurrence d'un double «L»:

grep l 2 lort.SMS

La sortie de la commande ci-dessus est:

Sept pour les nains de nains dans leurs salles de pierre, une bague pour les gouverner toutes, une bague pour les trouver, une bague pour les amener toutes, et dans l'obscurité les lier, 

Avec la même syntaxe, nous pouvons spécifier un nombre minimum d'occurrences, en utilisant X,, ou toute une gamme possible, en utilisant x, y, où X et y représenter, respectivement, le nombre minimum et le nombre maximum de répétitions de l'élément précédent.

Alternance

Lorsque nous travaillons avec des expressions régulières étendues, nous avons également accès au | méta-personnage, également appelé infli opérateur. En l'utilisant, nous pouvons rejoindre deux expressions régulières, produisant une expression qui correspondra à toute chaîne qui correspond à l'une ou l'autre des expressions alternatives.

Il est important de remarquer que les deux côtés du infli L'opérateur va toujours essayer d'être apparié: cela signifie que cet opérateur ne fonctionne pas comme le conditionnel ou Opérateur, où le côté droit n'est évalué que si le côté gauche est faux: cela peut être vérifié en observant la sortie de la commande suivante:

$ grep -n -e '^ o | l 2' lOTR.Txt 2: Sept pour les nains de nains dans leurs salles de pierre, 4: un pour le Seigneur des Ténèbres sur son trône noir 6: un anneau pour les gouverner tous, une bague pour les trouver, 7: une bague pour les amener toutes, Et dans l'obscurité les lier, 

Observez la sortie: chaque ligne commençant par la capitale «O», ou contenant un double «l» a été incluse dans la sortie. En ligne 6 et 7, Cependant, les deux expressions sur le côté gauche et droit du infli L'opérateur a produit un match. Ceci, comme indiqué ci-dessus, signifie que les deux côtés de l'opérateur sont évalués et si les deux produisent un match, les deux matchs sont inclus.

Fgrep

Si, par défaut, Grep prend en charge les opérateurs d'expressions régulières de base et en utilisant le -E option ou faire un coup de pouce Nous pouvons utiliser des expressions régulières étendues, avec le -F commutateur (abréviation pour les cordes-fixe) ou fgrep, Nous pouvons demander au programme de toujours interpréter un modèle comme une liste de chaînes fixes.

Cela signifie que les cordes sont toujours essayées d'être jumelées littéralement, et tous les méta-personnages perdent leur signification particulière. Cela peut être utile lorsque vous opérez sur un texte ou une chaîne qui contient beaucoup de caractères qui peuvent être considérés comme des opérateurs sans avoir à les échapper manuellement.

Réflexions de clôture

Dans ce tutoriel, nous avons appris à connaître le grep Commande Unix. Nous avons vu comment pouvons-nous l'utiliser pour trouver des correspondances dans un texte en utilisant des expressions régulières et nous avons également examiné le comportement de ses variantes: faire un coup de pouce et fgrep. Nous avons examiné des options très utiles comme -je, qui peut être utilisé pour effectuer des recherches insensibles à des études.

Enfin, nous avons fait une visite de certains des opérateurs d'expressions régulières les plus utilisés. Grep est définitivement l'un des outils système les plus importants et a une documentation très exhaustive: le consultation est toujours une bonne idée!

Tutoriels Linux connexes:

  • Une introduction à l'automatisation Linux, des outils et des techniques
  • Advanced Bash Regex avec des exemples
  • Masterring Bash Script Loops
  • Choses à installer sur Ubuntu 20.04
  • Boucles imbriquées dans les scripts bash
  • Python Expressions régulières avec des exemples
  • Mint 20: Mieux que Ubuntu et Microsoft Windows?
  • Bash regexps pour les débutants avec des exemples
  • Tutoriel de débogage GDB pour les débutants
  • Manipulation des mégadonnées pour le plaisir et le profit Partie 3