Pages

mardi 6 novembre 2012

Sed tout puissant

Il y 3 semaines environ je cherchais le moyen d'utiliser la commande sed avec une regex sur plusieurs lignes. En fait je voulais transformer tous les /\+\n\s+""/ en rien du tout (oui, les supprimer…). Sauf que comme tel, ça ne fonctionne pas, sed comme beaucoup de commandes unix fonctionne par ligne. Après de lourdes et pompeuses recherches d'au moins 7 secondes montre en main, je suis tombé sur la solution.

Pour ce faire, il suffit d'un identifiant, un petit label, une information de multi-ligne au milieu et 3 autres bricoles ; rien que ça :D.
Ce qui se traduit par:

sed -e :a -e N -e '$!ba' -e s'/\+\n\s+""//g'

Et en version courte:

sed ':a;N;$!ba;s/\+\n\s+""//g'

Je sais ce que vous vous demandez: pourquoi il n'y a pas -e dans la version courte ?
Mais parce que c'est la version courte, évidemment !

Sinon dans une moindre mesure.

:a
pour créer un identifiant, mais il peut très bien se nommer bidule
N
pour indiquer plusieurs lignes
$!ba
combinaison pour indiquer plein de choses, la seule dont je suis sûr c'est que b demande un identifiant (ici 'a')…

N peut être utilisé tout seul mais à ce moment c'est comme si on découpait le fichier par nombres de lignes égales à celle de la regex et qu'on les traitait indépendamment. Résultat, il peut y avoir des trous.

$ cat t
titi
titi
toto
titi
titi
$ sed ':a;N;$!ba;s/titi\ntiti/tutu/g' t
tutu
toto
tutu
$ sed 'N;s/titi\ntiti/tutu/g' t
tutu
toto
titi
titi

Et en bonus

sed 2,5s/e/U/g #remplace e par U à partir de la ligne 2 jusqu'à la 5.
sed "/$debut/,/$fin/"s/A/a/g #depuis $debut jusqu'à $fin.
sed "/$debut/,+5"s/A/a/g #depuis $debut et sur 5 ligne.

Aucun commentaire: