Re: [SHELL] remplacer un caractère dans une sous-chaine
Jacques L'helgoualc'h a écrit, vendredi 21 décembre 2007, à 19:22 :
> Sylvain Sauvage a écrit, vendredi 21 décembre 2007, à 10:31 :
[...]
> > > 3/ Recoller les morceaux... (en exercice :)
> >
> > Ah, ah, la technique habituelle des profs quand ça devient
> > scabreux : « en exercice », « c???est trivial »???
>
> Ici, ça n'a rien de très scabreux.
>
> > Je préfère le « vous verrez ça l???année prochaine » :o)
>
> Il y a un précédent bien connu, où la marge n'était pas assez grande :)
>
> Réponse(s) vendredi prochain.
Exercice : mettre en majuscules et double espacement le texte entre
crochets précédés de « Cap » ou « Maj ».
Une solution :
sed -re 's/\b(Maj|Cap)\[([^][]+)\]/\1BALISE_debut\n\2\nBALISE_fin\n/g' <texte |\
sed -e '/BALISE_debut$/,/^BALISE_fin$/{/BALISE_/!{s/./ \u&/g;s/^ //}}' |\
sed -ne 'H;${g;s/^\n//;s/BALISE_debut\n/\[/g;s/\nBALISE_fin\n/\]/g;p}'
Dans le premier sedscript, on peut remplacer la seconde parenthèse par
« ([^][]*\[[^][]*\][^][]*|[^][]+) », pour traiter le cas d'un crochet
emboîté de niveau 2 ; le lecteur courageux peut aller plus loin...
Version commentée du troisième :
sed -n -e '
H # stockage de toutes les lignes dans le « hold space »,
${# et à la fin, récupération du hold space
g
# suppression de la ligne 0
s/^\n//1
# remplacement global des balises,
s/BALISE_debut\n/\[/g
s/\nBALISE_fin\n/\]/g
# et sortie du résultat
p
}'
Variante avec traitement local pour éviter de stocker tout le fichier
en mémoire, et/ou attendre la fin du pipe :
sed -e '
# Boucle de reconstitution d'une ligne originale
: Ligne
/BALISE_debut$/{
# Boucle interne de lecture de bloc traité
: Bloc
N
/\nBALISE_fin$/! b Bloc
# Remplacement des deux balises
s/BALISE_debut\n/\[/1
N
s/\nBALISE_fin\n/\]/1
b Ligne
}'
On peut essayer de regrouper en deux, voire un seul script Sed ---
mais la lisibilité peut en souffrir ().
Bonnes fêtes à tous,
--
Jacques L'helgoualc'h
Reply to: