Re: [ssfr] sed : remplacer guillemets anglais par guillements français

[ Thread Index | Date Index | More debianworld.org/shellscript-fr Archives ]


On Sat, Nov 01, 2008 at 02:36:45PM +0100, dlist@xxxxxxxxxx wrote:
> Bonjour,
> 
> J'ai plusieurs fichiers tex où il faudrait remplacer les " par des «»,
> je me dis que c'est pour sed ça.
<snip>
> Faut traduire ça en sed maintenant, et c'est là que ça se complique
> (pour moi).

ecrivont le ensembles :)

> le motif est
> "

  "

> puis 0,1 ou plus espaces

  " *

 le * qui suit l'espace signifiant 0,1 ou plus de fois le caractere ou
 l'expression qui precede.

 si l'on souhaite matcher un caractere parmis en ensemble de caracteres
 possibles il suffit de definir le(s) caracteres en question entre
 crochets, on peut donc ecrire egalement:

  "[ ]*

 et pour matcher indifferement un espace ou une tabulation, POSIX
 nous permet d'utiliser [:blank:] sachant que les crochets sont ici
 utilisé pour delimiter un symbole special. La repetition d'un caractere
 entre crochets comme le ':' n'a aucun sens pour la definition d'un
 ensemble de caracteres, car il n'y a pas de notion d'ordre. donc:

  "[[:blank:]]*

> puis un mot

 que l'on va definir comme etant une suite de caracteres quelconques sans
 espace(s), on peut utiliser les crochet avec le symbole POSIX [:graph:]
 (donc [[:graph:]]) qui signifie tout les caracteres affichables et visibles
 mais pas les espaces. ou bien la negation de ce qui est entre crochet
 qui se fait avec un ^ apres la premier crochet, donc

  [^ ]+  ou  [^[:blank:]]+  ou  [[:graph:]]+

 le + signifiant 1 ou plus de fois de caractere ou l'expression qui
 precede. notre expression complete devient donc:

  " *[^ ]+  ou  "[ ]*[^ ]+  ou  "[[:blank:]]*[^[:blank:]]+

 (je me contenterais d'utiliser la negation)

> puis 0,1 ou plus espaces

 comme au debut notre expression complete devenant:

  " *[^ ]+ *

 ou

  "[ ]*[^ ]+[ ]*

 ou

  "[[:blank:]]*[^[:blank:]]+[[:blank:]]*

> et enfin "

  donc:  "[[:blank:]]*[^[:blank:]]+[[:blank:]]*"

pour le fonctionnement par defaut du GNU sed il nous faut echapper
le + pour qu'il garde sa signification speciale, donc :

  "[[:blank:]]*[^[:blank:]]\+[[:blank:]]*"

 ou

  " *[^ ]\+ *"

> Ce motif doit être remplacé par
> 
> «un_espace_insécable puis le mot puis un_espace_insécable puis »

il nous faut donc recuperer le mot dans l'expression precedente, on
l'isole en mettant la partie concernée de l'expression entre parentheses
echappées (pour le GNU sed par defaut toujours), donc:

  "[[:blank:]]*\([^[:blank:]]\+\)[[:blank:]]*"

 ou

  "[ ]*\([^ ]\+\)[ ]*"

 ou

  " *\([^ ]\+\) *"

et il ne reste plus qu'a construire le resultat en utilisant une back
reference sur la partie isolée, comme il n'y en a qu'une c'est donc \1,
\0 representant l'ensemble de l'expression et \X la X eme sous expression
isolée. cela nous donne:

  « \1 »

et on passe le tout a la commande s de sed dont la syntaxe sur une seule
ligne est:

 s
 <separateur>
 <expression a matcher>
 <separateur>
 <remplacement>
 <separateur>
 <options facultatives>

 l'option g indique de remplacer toutes les occurences matchées sur une
 ligne, le comportement par defaut etant de ne remplacer que la premiere,
 le separateur est lui un caractere quelconque; je choisi ici la virgule,
 cela nous donne:

  sed 's,"[[:blank:]]*\([^[:blank:]]\+\)[[:blank:]]*",« \1 »,g' < input > output

 ou

  sed 's,"[ ]*\([^ ]\+\)[ ]*",« \1 »,g' < input > output

 ou

  sed 's," *\([^ ]\+\) *",« \1 »,g' < input > output

 voila pour une solution simpliste, sachant qu'elle suppose que les
guillemets ouvrantes et fermantes ainsi que le mot qu'elles delimitent
se trouvent toujours "balancés" sur une seule et meme ligne.

> Merci pour vos suggestions.

                                        hope this help.


---


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/