next up previous contents Next: Insertion et effacement de Up: Flux et sed comme Previous: Utilisation de sed pour   Table des matières  

9.7 Sous-expressions d'expressions rationnelles.

Cette section explique comment faire la tâche apparemment complexe de permuter des parties de textes à l'intérieur d'un texte. Prenons, par exemple, la sortie de ls: supposons que vous vouliez isoler automatiquement la colonne ``taille''. sed peut effectuer ce type d'opération si vous utilisez la notation spéciale \ ( \) pour regrouper les parties d'une expression rationnelle. Avant de s'attaquer à ce problème, considérons deux exemples d'utilisation de sed avec des sous-expressions rationnelles qui nous viendrons à point nommé pour traiter le cas de ls. Premier exemple: la structure des sous-expressions rationnelles. Analysons:

sed -e 's/\(<[^ ]*\>\)\([ ]*\)\(<[^  ]*\>\)/\3\2\1/g' 


Notons que cette commande contient, pour <recherche-expreg>, le motif
\(<[^ ]*\>\)\([ ]*\)\(<[^ ]*\>\) qui est consituté de trois sous-expressions rationnelles: la 1 est \(<[^ ]*\>\); la 2 est \([ ]*\) et la 3 est \(<[^ ]*\>\). Le motif <remplace-texte> est constitué du numéro des trois sous-expressions rationnelles \3\2\1. Voyons la signification de cette commande.

La première sous expression \(<[^ ]*\>\) signifie \<. *\>, c'est-à-dire n'importe quel caractère (.) un nombre de fois indéfini (*) (il s'agit d'un mot au sens large). La seconde sous-expression \([ ]*\) signifie \[ ]*, c'est à dire un nombre arbitraire d'espaces (il s'agit d'une suite de blancs en nombre quelconque). La troisième sous-expression est identique à la première. Nous demandons ainsi à sed de rechercher un mot suivi de blancs, eux-mêmes suivis d'un autre mot.

Deuxième exemple: testons ce qui se produit quand vous exécutez ceci [On s'attend à ce que les trois premiers motifs, c'est-à-dire ``GNU'', `` '' ,``Linux'' soient traités de sorte que la permutation retourne Linux GNU. Puis, sed opère sur le reste du texte en prenant les trois motifs suivants: ``est'', `` '', ``génial'', qu'il permute.]:

sed -e 's/\(<[^ ]*\>\)\([ ]*\)\(<[^ ]*\>\)/\3\2\1/g'

GNU Linux est génial

Linux GNU génial est 



A présent, revenons à notre problème de ls (notez que ceci n'est vraiment qu'un exemple, car pour déterminer la taille des fichiers vous devriez utiliser la commande du). Voyons comment nous pourrions obtenir la taille en octets de tous les fichiers de notre répertoire: [NdT: faites bien attention à entourer d'espaces l'opérateur +.]

expr 0 `ls -l | grep '^-' | \

    sed 's/^\([^ ]*[ ]*\)\{4,4\}\([0-9]*\).*$/ + \2/'` 



Nous savons que, dans le cas des fichiers ordinaires, la sortie de ls -l commence par - . Nous utilisons grep pour éliminer les lignes qui ne commencent pas par - (ce que représente l'expression ls -l | grep '^-'). Si nous faisions cela, nous verrions que la sortie (qui maintenant ne concerne plus que les fichiers) est partagée en quatre colonnes d'information qui ne nous intéressent pas, avant que nous ne trouvions la colonne avec les tailles de fichiers.

Pour effectuer le remplacement ultérieurement, il faut donc rechercher une chaîne de caractères suivie d'un nombre quelconque d'espaces à l'aide de la première sous-expression rationnelle \([^ ]*[ ]*\) et ce, quatre fois exactement: d'où le complément \{4,4\}. Après quoi, nous trouverons une série de chiffres allant de 0 à 9 ayant une occurrence quelconque d'où la seconde sous-expression rationnelle \([0-9]*\). Ensuite viennent une série de caractères quelconques (.) en nombre indéterminé (*) à la fin ($) de la recherche. Tous ces éléments compris entre sed 's/ et + constituent donc le motif <recherche-expreg> que nous avons défini dans nos premiers exemples. Notez que nous avons fait l'impasse sur la notation \< \> pour les mots complets (voir la section 6.4). A la différence de grep, sed essaye de trouver les correspondances sur le nombre maximum de caractères autorisés, ce qui revient au même que de préciser que la recherche doit se faire sur des noms complets.

Vous pouvez essayer d'imaginer ce que retourne la commande ls -l | grep '^-' | sed 's/^\([^ ]*[ ]*\)\{4,4\}\([0-9]*\).*$/ + \2/' (ceci est un exemple):

+ 438

+ 1525

+ 76

+ 92146 


Donc, vous avez remplacé chaque ligne par la sous-expression \2 et vous l'avez faite précédée d'un signe +. Les guillemets inversés vous retournent la sortie vers expr qui effectue la somme en ignorant tous les caractères de nouvelle ligne alors même que chaque nouvelle somme est l'objet d'une nouvelle ligne. Le seul problème (mineur) est que la première ligne débute par un signe + qu'aucun nombre ne précède. Ceci devrait amener expr à émettre un message d'erreur. Pour contourner ce problème, il suffit d'introduire 0 suite à la commande expr de manière à commencer le calcul ainsi: 0 + ... .


next up previous contents Next: Insertion et effacement de Up: Flux et sed comme Previous: Utilisation de sed pour   Table des matières  
1-01-2006