EEIJ

Païou : Mandriva Linux depuis 2002. Aujourd'hui, c'est Mageia Linux


Sommaire


Conforme à XHTML 1.0 Strict Conforme à CSS!

On se lasse de tout, sauf de comprendre.
Attribué à Virgile.

grep, sed et les regex

Historique

28 août 2012 : Création de cette page.

Difficulté

Pour : un esprit logique et curieux.

 Introduction

Deux commandes très utiles pour examiner le contenu d'un fichier et de modifier son contenu : grep et sed
Ces deux commandes autorisent l'utilisation des expressions régulières ou Regex.

Il est donc judicieux de voir ce que sont ces expressions régulières.

 Les expressions régulières

Une expression régulière (appelée aussi expression rationnelle) est une chaîne de caractères, contenant un motif et des métacaractères (caractères ayant une signification autre que la signification habituelle). Elle est utilisée par nombre de logiciels Unix, dont grep, sed et les tests.

Un premier exemple, avec grep, va illustrer ces notions de regex :
grep sert à retrouver une chaîne de caractères, appelée motif, dans un fichier.

grep "mageia" fichier permet de trouver les lignes qui contiennent le motif mageia
Nota : le motif mageia peut être entouré par n'importe quels autres caractères, ex mageiaphiles, nomageiaphiles, mageiaphobes ...

grep "^mageia" fichier permet de trouver les lignes qui commencent par le motif mageia

Les regex font appel à plusieurs notions.

Haut

 Caractère littéral

Caractère littéral

Tout caractère qui n'a pas d'autre signification que celle qui lui est habituelle, tel que a, toto, mageia ...

 Métacaractère

Le point

Le point remplace n'importe quel caractère littéral (un jocker) dans un motif, mais avec obligation d'un caractère

Le caractère littéral . peut être rétabli en l'échappant : \.

Le symbole de début et de fin de ligne

Il est possible de préciser que le motif doit être placé en début ou en fin de ligne

Haut

Le symbole de classe de caractères

Les crochets [ ] permettent de définir un choix de caractères. Voici quelques exemples :

Ils permettent également de définir une exclusion

Le symbole de quantification du nombre de caractères

Il y a 3 symboles permettant de définir le nombre de caractères identiques à chercher :

Quelques exemples :

Le regroupement

Les parenthèses ( ) permettent de grouper des caractères pour, par exemple, définir la portée d'une quantification. Exemple

 La commande grep

La commande grep affiche les lignes contenant une chaîne de caractères donnée et qu'elle cherche dans le(s) fichier(s) indiqué(s).
Syntaxe : grep [options] motif fichier(s)
Exemple : grep paiiou /etc/passwd donne : paiiou:x:500:500:Paiiou:/home/paiiou:/bin/bash

 Les options

Les options qui m'intéressent sont les suivantes :

Il existe encore bon nombre d'autres options. man grep pour en savoir plus.

 Les tuyaux (pipes)

grep est souvent utilisé à la suite d'une autre commande :

Exemple 1 :
rpm -qa | grep mageia affiche la liste des paquetages installés et qui contiennent le motif mageia

Exemple 2, avec affichage de plusieurs lignes après une concordance :
LIGNE=$(grep -n -A 3 'autophoto' /etc/xdg/$VOL | grep 'command') recherche la ligne (avec son numéro) qui contient le motif command et qui vient peu après une ligne qui contient autophoto
LIGNE=${LIGNE%%-*} ne retient que le numéro de la ligne.

Haut

 La commande sed

sed est un "éditeur de flux" (Stream EDitor). Cet outil permet de manipuler les fichiers textes de façon automatique, de rendre les scripts (beaucoup) plus puissants, etc.
Avant de commencer, il est fondamental de bien comprendre le fonctionnement de sed. C'est ce qui permet d'en connaitre les limites, de savoir ce que l'on peut faire et ne pas faire avec, à quoi est-il adapté, etc.

En premier lieu, il faut retenir que sed fonctionne en mode «flux», c'est-à-dire que le flux en entrée (fichier ou autre) est traité ligne par ligne.
Ensuite, il convient de noter deux façons d'utiliser sed :

  1. La méthode "classique", qui consiste à appliquer la commande sur le flux d'entrée, et récupérer le flux de sortie. Par exemple, on applique sed sur un fichier, et on redirige la sortie sur un autre fichier.
  2. La méthode "directe", avec l'option sed -i, qui applique la commande directement sur le fichier passé en entrée.

La syntaxe

sed [OPTION]... {script-only-if-no-other-script} [input-file]
On voit que la commande sed demande un script avec les actions à effectuer sur le fichier d'entrée. Il existe à nouveau deux manières

Haut

 L'adressage

Adressage par ligne

On spécifie la(les) ligne(s) sur laquelle(lesquelles) les commandes doivent être appliquées
sed -e '4d; 7d' fichier suppression ligne 4; suppression ligne 7
sed -e '4,7d' fichier suppression de toutes les lignes entre 4 et 7 (incluses)

Adressage par motif

On spécifie un motif à rechercher, éventuellement à l'aide des expressions rationnelles.
sed -e '/^#/d' fichier suppression des lignes commençant par # (commentaires)
sed -e '/motif1/,/motif2/d' fichier suppression de toutes les lignes entre le motif1 et le motif2 (lignes contenant les motifs incluses)

 Mode silencieux

Par défaut, sed n'affiche aucune ligne. On utilise ce mode avec la commande p (print). Dans ce cas, sed n'affiche que les lignes avec concordance.
sed -n '/motif/p' fichier affiche juste les lignes avec le motif

Remarque

Les exemples qui seront donnés ci-dessous concernent la modification du fichier en place, c'est-à-dire avec l'option -i. C'est ce qui m'intéresse effectivement.

Haut

 Substitution

C'est probablement la commande la plus utilisée. Le motif peut être une chaîne normale, une regex, une regex étendue (avec -r)
sed -i 's/la/LA/' fichierremplace la première occurrence rencontrée, de chaque ligne
sed -i 's/la/LA/g' fichierremplace toutes les occurrences rencontrées, de chaque ligne
sed -i 's/la/LA/2' fichierremplace uniquement la 2ème occurrence rencontrée, de chaque ligne
sed -ire 's/^# *//' fichierdé-commente les lignes commençant par une dièse, et supprime les espaces en début de ligne (le * est un métacaractère signifiant 0 ou plus).

Le caractère de séparation / peut être remplacé par un autre caractère. C'est notamment intéressant lorsque le motif comprend un chemin d'accès, avec des /. J'utilise alors ! par ex :
sed -i "s!^#greeter-setup-script=.*!greeter-setup-script=/usr/bin/numlockx on!" fichier

Haut

 Insertion d'une ligne

Il s'agit d'insérer une ligne (ou plusieurs) avant une autre, définie par son numéro ou par un motif. Si le motif est trouvé plusieurs fois, il y a également plusieurs insertions.

Syntaxe

sed -i '15i\Ligne à insérer' insère la nouvelle ligne avant la ligne 15.
sed -i '/motif/i\Ligne à insérer' insère la nouvelle ligne avant chaque ligne qui contient le motif.

Haut

 Ajout d'une ligne

Il s'agit d'ajouter une ligne (ou plusieurs) après une autre, définie par son numéro ou par un motif. Si le motif est trouvé plusieurs fois, il y a également plusieurs ajouts.

Syntaxe

sed -i '15a\Ligne à ajouter' ajoute la nouvelle ligne après la ligne 15.
sed -i '/motif/a\Ligne à ajouter' ajoute la nouvelle ligne après chaque ligne qui contient le motif.

Haut

 Remplacement d'une ligne

Il s'agit, ici, de remplacer toute une ligne et pas de substituer dans une ligne.

Syntaxe

sed -i '15c\Ligne à placer' remplace l'ancienne ligne 15 par la nouvelle.
sed -i '/motif/c\Ligne à placer' remplace chaque ligne qui contient le motif par la nouvelle ligne.

Haut