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'
|
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
|
expr 0 `ls -l | grep '^-' |
\
sed 's/^\([^ ]*[ ]*\)\{4,4\}\([0-9]*\).*$/ + \2/'`
|
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 + ... .