Voici une brève introduction aux utilitaires de traitement de texte sed et awk. Nous allons traiter ici uniquement quelques commandes de base, mais qui devraient suffire pour comprendre des expressions sed et awk simples à l'intérieur de scripts shell.
sed : éditeur de fichiers texte non interactif
awk : langage de traitement de motifs orienté champs avec syntaxe proche de C
Malgré toutes leurs différences, les deux utilitaires partagent une syntaxe d'appel similaire, utilisent les expressions rationnelles, lisent sur l'entrée standard stdin par défaut, et envoient leurs résultats la sortie standardstdout. Ce sont de bons outils UNIX et ils travaillent bien ensemble. La sortie de l'un peut être envoyée via un tube pour alimenter l'autre, et leurs capacités combinées donnent aux scripts shell un peu de la puissance de Perl.
Une différence importante entre ces utilitaires est que si les scripts shell peuvent passer des arguments facilement à sed, c'est plus compliqué avec awk (voir l'Exemple 36.5, « Un script d'appel autour d'un autre script awk » et l'Exemple 28.2, « Passer une référence indirecte à awk »).
Sed est un éditeur en ligne ("stream editor") non interactif [138] . Il reçoit du texte en entrée, que ce soit à partir de stdin ou d'un fichier, réalise certaines opérations sur les lignes spécifiées de l'entrée, une ligne à la fois, puis ressort le résultat vers stdout ou vers un fichier. À l'intérieur d'un script shell, sed est souvent un des différents outils composant un tube.
Sed détermine sur quelles lignes de son entrée il va opérer à partir d'une plage d'adresses qui lui a été fournie. [139] Cette plage d'adresses est définie soit par des numéros de ligne soit par un motif à rechercher. Par exemple, 3d indique à sed qu'il doit supprimer la ligne 3 de l'entrée et /Windows/d demande à sed de supprimer toutes les lignes de l'entrée qui contiennent « Windows ».
Parmi toutes les opérations de la boîte à outils sed, nous nous occuperons principalement des trois les plus communément utilisées. Il s'agit de printing (NdT : affichage vers stdout), deletion (NdT : suppression) et substitution (NdT : euh... substitution :).
Tableau C.1. Opérateurs sed basiques
Opérateur | Nom | Effet |
---|---|---|
[plage-d-adresses]/p | Affiche la [plage d'adresse] spécifiée | |
[plage-d-adresses]/d | delete | Supprime la [plage d'adresse] spécifiée |
s/motif1/motif2/ | substitute | Substitue motif2 à la première instance de motif1 sur une ligne |
[plage-d-adresses]/s/motif1/motif2/ | substitute | Substitue motif2 à la première instance de motif1 sur une ligne, en restant dans la plage-d-adresses |
[plage-d-adresses]/y/motif1/motif2/ | transform | remplace tout caractère de motif1 avec le caractère correspondant dans motif2, en restant dans la plage-d-adresses (équivalent de tr) |
g | global | Opère sur chaque correspondance du motif à l'intérieur de chaque ligne d'entrée de la plage d'adresses concernée |
La substitution opère seulement sur la première occurrence d'un motif à l'intérieur de chaque ligne, sauf si l'opérateur g (global) est ajouté à la commande substitute.
À partir de la ligne de commande et dans un script shell, une opération sed peut nécessiter de mettre entre guillemets et d'utiliser certaines options.
sed -e '/^$/d' $nomfichier # L'option -e fait que la chaîne de caractère suivante est interprétée comme #+ une instruction d'édition. # (Si vous passez une seule instruction à sed, le "-e" est optionnel.) # Les guillemets "forts" ('') empêchent les caractères de l'ER compris dans #+ l'instruction d'être interprétés comme des caractères spéciaux par le corps #+ du script. # (Ceci réserve l'expansion de l'ER de l'instruction à sed.) # # Opère sur le texte contenu dans le fichier $nomfichier.
Dans certains cas, une commande d'édition sed ne fonctionnera pas avec des guillemets simples.
nomfichier=fichier1.txt motif=BEGIN sed "/^$motif/d" "$nomfichier" # fonctionne comme indiqué # sed '/^$motif/d' "$nomfichier" a des résultats inattendus. # Dans cette instance, avec des guillemets forts (' ... '), #+ "$motif" ne sera pas étendu en "BEGIN".
sed utilise l'option -e pour spécifier que la chaîne suivante est une instruction ou un ensemble d'instructions. Si la chaîne ne contient qu'une seule instruction, alors cette option peut être omise.
sed -n '/xzy/p' $nomfichier # L'option -n indique à sed d'afficher seulement les lignes correspondant au #+ motif. # Sinon toutes les lignes en entrée s'afficheront. # L'option -e est inutile ici car il y a une seule instruction d'édition.
Tableau C.2. Exemples d'opérateurs sed
Notation | Effet |
---|---|
8d | Supprime la 8è ligne de l'entrée. |
/^$/d | Supprime toutes les lignes vides. |
1,/^$/d | Supprime les lignes du début à la première ligne vide (inclue). |
/Jones/p | Affiche seulement les lignes contenant « Jones » (avec l'option -n). |
s/Windows/Linux/ | Substitue « Linux » à chaque première instance de « Windows » trouvée dans chaque ligne d'entrée. |
s/BSOD/stability/g | Substitue « stability » à chaque instance de « BSOD » trouvée dans chaque ligne d'entrée. |
s/ *$// | Supprime tous les espaces à la fin de toutes les lignes. |
s/00*/0/g | Compresse toutes les séquences consécutives de zéros en un seul zéro. |
/GUI/d | Supprime toutes les lignes contenant « GUI ». |
s/GUI//g | Supprime toutes les instances de « GUI », en laissant le reste de la ligne intact. |
Substituer une chaîne vide (taille zéro) à une autre est équivalent à supprimer cette chaîne dans une ligne de l'entrée. Le reste de la ligne reste intact. Appliquer s/GUI// à la ligne
The most important parts of any application are its GUI and sound effects
donne
The most important parts of any application are its and sound effects
L'antislash force la continuité sur la ligne suivante pour la commande sed. Ceci a pour effet d'utiliser la nouvelle ligne comme fin de ligne de la chaîne de remplacement.
s/^ */\ /g
Cette substitution remplace les espaces débutant les lignes par un retour chariot. Le résultat final est le remplacement des indentations de paragraphes par une ligne vide entre les paragraphes.
Une plage d'adresses suivie par une ou plusieurs opérations peut nécessiter des accolades ouvrantes et fermantes avec les retours chariot appropriés.
/[0-9A-Za-z]/,/^$/{ /^$/d }
Ceci supprime seulement la première de chaque ensemble de lignes vides consécutives. Ceci peut être utile pour espacer de manière égale un fichier texte mais en conservant les lignes vides entre paragraphes.
Le délimiteur le plus généralement utilisé par sed est /. Néanmoins, sed autorise d'autres délimiteurs, comme %. C'est utile quand / fait partie d'une chaîne de remplacement, comme dans le chemin d'un fichier. Voir Exemple 11.9, « Rechercher les auteurs de tous les binaires d'un répertoire » et Exemple 16.32, « Supprimer les commentaires des programmes C ».
Une façon rapide de doubler les espaces dans un fichier texte est sed G nomfichier.
Pour des exemples illustrant l'usage de sed à l'intérieur de scripts shell, jetez un oeil aux exemples suivants :
Exemple 36.2, « Un script d'appel légèrement plus complexe »
Exemple A.2, « rn : Un utilitaire simple pour renommer des fichiers »
Exemple 16.27, « Utiliser column pour formater l'affichage des répertoires »
Exemple A.12, « behead: Supprimer les en-têtes des courriers électroniques et des nouvelles »
Exemple A.16, « tree: Afficher l'arborescence d'un répertoire »
Exemple A.17, « tree2 : un autre script d'arborescence de répertoires »
Exemple 16.32, « Supprimer les commentaires des programmes C »
Exemple 11.9, « Rechercher les auteurs de tous les binaires d'un répertoire »
Exemple A.1, « mailformat : Formater un courrier électronique »
Exemple 16.14, « Générer des nombres aléatoires de dix chiffres »
Exemple 16.12, « Analyse de fréquence d'apparition des mots »
Exemple 16.19, « Rechercher des définitions dans le dictionnaire Webster de 1913 »
Pour un traitement plus en profondeur de sed, vérifiez les références appropriées dans la Bibliographie.