Païou : Mandriva Linux depuis 2002. Aujourd'hui, c'est Mageia Linux
On se lasse de tout, sauf de comprendre.
Attribué à Virgile.
28 août 2012 : Création de cette page.
Pour : un esprit logique et curieux.
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.
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.
Tout caractère qui n'a pas d'autre signification que celle qui lui est habituelle, tel que a, toto, mageia ...
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 : \.
Il est possible de préciser que le motif doit être placé en début ou en fin de ligne
Les crochets [ ] permettent de définir un choix de caractères. Voici quelques exemples :
Ils permettent également de définir une exclusion
Il y a 3 symboles permettant de définir le nombre de caractères identiques à chercher :
Quelques exemples :
Les parenthèses ( ) permettent de grouper des caractères pour, par exemple, définir la portée d'une quantification. Exemple
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 qui m'intéressent sont les suivantes :
Il existe encore bon nombre d'autres options. man grep pour en savoir plus.
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.
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 :
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
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)
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)
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
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.
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
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.
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.
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.
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.
Il s'agit, ici, de remplacer toute une ligne et pas de substituer dans une ligne.
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.