Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[HS] encoding avec sed

4 réponses
Avatar
Jean-Michel OLTRA
Bonjour,


Un HS, mais je ne m'explique pas le comportement de sed.

Sur un fichier encodé en utf-8, je veux remplacer les espaces insécables
par de véritables espaces :

sed -i 's/\xa0/\x20/g' fichier.sql

Mais en réalité, l'espace insécable est bien remplacée, mais il y a un Â
avant, et le fichier est encodé en latin1.

Si le fichier est en latin1 avant la substitution, l'espace est
remplacée, et le fichier est converti en utf-8, ce que je trouve normal
vu que le terminal l'est également (peut-être qu'il n'y a pas de
rapport).

Si quelqu'un sait ? Ce n'est pas vital, juste curieux, pour moi.

--
jm

A.E.L. Sarl (R.C.S CASTRES 490843240)
http://www.spidboutic.fr


--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/DebFrFrenchLists
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to debian-user-french-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

4 réponses

Avatar
Sylvain Sauvage
Jean-Michel OLTRA, samedi 6 décembre 2008, 12:17:13 CET


Bonjour,



’jour,

Un HS, mais je ne m'explique pas le comportement de sed.

Sur un fichier encodé en utf-8, je veux remplacer les espaces
insécables par de véritables espaces :

sed -i 's/xa0/x20/g' fichier.sql

Mais en réalité, l'espace insécable est bien remplacé e, mais
il y a un  avant, et le fichier est encodé en latin1.



Euh, c’est pas très clair. Le fichier de départ est en utf-8
et le fichier d’arrivée en latin1 ?

Déjà, si le fichier de départ est en utf-8, alors l†™espace
insécable est xc2xa0, pas xa0. xa0 n’est pas un caractà ¨re
utf-8.

Ensuite, si tu enlèves xa0 sans enlever xc2, alors le
fichier n’est plus valide vis à vis de l’utf-8 (xc2x 20 n’est
pas un caractère utf-8 : aucun caractère ascii ne doit / peut
apparaître comme partie d’un autre caractère). Et si ce n ’est
plus de l’utf-8, c’est considéré comme du latinX …

Et c’est ce que j’ai chez moi :

$ cat > bla
épaue rauet
^D ^ espace insécable

$ file bla
bla: UTF-8 Unicode text

$ sed -i -e 's/xa0/x20/g' bla
^ ne pas oublier de quoter…

$ file bla
bla: ISO-8859 text

Je regarde dedans (zile p.ex. ne sais pas gérer l’Unicode, ce
qui finalement est assez pratique pour ce genre de repérage) et
je vois bien le 302 (=xc2) tout seul alors que le é est bien
un 303251.

Si le fichier est en latin1 avant la substitution, l'espace est
remplacée, et le fichier est converti en utf-8, ce que je
trouve normal vu que le terminal l'est également (peut-être
qu'il n'y a pas de rapport).



Hmm, pas chez moi :

[on reprend avec un bla tout neuf]
$ recode u8..l9 bla

$ file bla
bla: ISO-8859 text

$ sed -i -e 's/xa0/x20/g' bla

$ file bla
bla: ISO-8859 text

Si quelqu'un sait ? Ce n'est pas vital, juste curieux, pour
moi.



--
Sylvain Sauvage

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/DebFrFrenchLists
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Avatar
Frank Lin PIAT
Bonjour,

Un HS, mais je ne m'explique pas le comportement de sed.

Sur un fichier encodé en utf-8, je veux remplacer les espaces insécables
par de véritables espaces :

sed -i 's/xa0/x20/g' fichier.sql



en UTF-8, un blanc non-sécable, ça utilise 2 octets (c2a0)
http://www.fileformat.info/info/unicode/char/00a0/index.htm

D'ailleurs:
echo -n "### ###" > test
hexdump test -C
00000000 23 23 23 c2 a0 23 23 23 |###..###|
On vois bien qu'il y a 2 octets (évidemment il fallait taper Alt-Espace
entre les caractère "#")

Donc:
sed -i 's/xc2xa0/ /g' test

Mais en réalité, l'espace insécable est bien remplacée, mais il y a un Â
avant, et le fichier est encodé en latin1.



Ce que tu as fait c'est de remplacer la séquence d'octet "c2a0" (qui est
un blanc insécable) par la séquence "20a0".
On se retrouve avec x20 est effectivement un blanc "normal", précédé de
l'octet "xc2".

Ton éditeur de texte se retrouve avec une séquence d'octets qui n'est
pas valide en UTF-8 (un octet entre xC2 et xDF doit être suivi de deux
octets compris entre x80 et xBF voir [2])... du coup, ton editeur
continue d'essayer de détecter l'encodage, et choisi latin1, dans ton
cas précis.

Franklin


[2] http://www.fileformat.info/info/unicode/utf8.htm

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/DebFrFrenchLists
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Avatar
Jean-Michel OLTRA
Bonjour,


Le samedi 06 décembre 2008, Sylvain Sauvage a écrit...


> sed -i 's/xa0/x20/g' fichier.sql
>
> Mais en réalité, l'espace insécable est bien remplacée, mais
> il y a un  avant, et le fichier est encodé en latin1.



Euh, c’est pas très clair. Le fichier de départ est en utf-8
et le fichier d’arrivée en latin1 ?



Oui, mais je me base sur vim pour avoir l'encodage (:set fileencoding?)
et le code du caractère (ga). Et l'encodage utf-8 est différent
d'unicode, qui est juste une norme de représentation

Déjà, si le fichier de départ est en utf-8, alors l’espace
insécable est xc2xa0, pas xa0. xa0 n’est pas un caractère
utf-8.



Voilà l'erreur. Vim me donne 00a0 pour l'espace insécable. Mais :
http://fr.wikipedia.org/wiki/Table_des_caract%C3%A8res_Unicode_(0000-0FFF)#Latin_basique
donne bien 00a0 pour nbsp en Unicode

Ensuite, si tu enlèves xa0 sans enlever xc2, alors le
fichier n’est plus valide vis à vis de l’utf-8 (xc2x20 n’est
pas un caractère utf-8 : aucun caractère ascii ne doit / peut
apparaître comme partie d’un autre caractère). Et si ce n’est
plus de l’utf-8, c’est considéré comme du latinX…



C'est ce qui doit se passer, puisqu'il reste, pour vim xc2 et il
m'affiche «Â » (Â qui serait 00c2 en unicode suivi d'une espace.

En fait vim m'affiche l'encodage utf-8, mais me donne le code hexa du
caractère en unicode, et pas en utf-8, donc la substitution ne se passe
pas comme je le vois, puisque je me base sur ce qu'il me donne avec la
combinaison de touches ga.

> Si le fichier est en latin1 avant la substitution, l'espace est
> remplacée, et le fichier est converti en utf-8, ce que je
> trouve normal vu que le terminal l'est également (peut-être
> qu'il n'y a pas de rapport).



Hmm, pas chez moi :



[on reprend avec un bla tout neuf]
$ recode u8..l9 bla



$ file bla
bla: ISO-8859 text



$ sed -i -e 's/xa0/x20/g' bla



$ file bla
bla: ISO-8859 text



Si je fais le :
sed -i 's/xc3xa0/x20/g' sur un fichier utf-8 (selon vim), `file` me
le donne en utf-8 unicode text avant la substitution. Après la
substitution, `file` me le donne en ASCII text, alors que vim me le
donne bien en encodage utf-8

Merci de ton éclairage.

--
jm

A.E.L. Sarl (R.C.S CASTRES 490843240)
http://www.spidboutic.fr


--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/DebFrFrenchLists
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Avatar
Jacques L'helgoualc'h
Jean-Michel OLTRA a écrit, samedi 6 décembre 2008, à 12:17 :
Bonjour,



bonsoir,

Un HS, mais je ne m'explique pas le comportement de sed.

Sur un fichier encodé en utf-8, je veux remplacer les espaces insécables
par de véritables espaces :

sed -i 's/xa0/x20/g' fichier.sql



Comme te l'a dit Sylvain, tu ne remplaces que le second octet de la
paire codant l'espace insécable en UTF-8.

Mais en réalité, l'espace insécable est bien remplacée, mais il y a un Â
avant, et le fichier est encodé en latin1.



Ou tout autre codage compatible...

Si le fichier est en latin1 avant la substitution, l'espace est
remplacée, et le fichier est converti en utf-8, ce que je trouve normal
vu que le terminal l'est également (peut-être qu'il n'y a pas de
rapport).



Si ton terminal est en UTF-8, tu aurais dû taper l'espace insécable dans
la substitution...

En complément à ceux de Sylvain, quelques essais en environnement latin1 :

~ $ cat texte
ascii pur sucre
espace normal
espace insecable (sans accent ;)
çédille latin1

~ $ recode ..utf8 <texte >texte_utf8
~ $ sed -i -e 's/latin1/UTF-8/' texte_utf8
~ $ diff texte texte_utf8
3,4c3,4
< espace insecable (sans accent ;)
< çédille latin1
---
espace insecable (sans accent ;)
çédille UTF-8




# remplacer l'octet :
~ $ sed -e 's/xa0/_/g' texte texte_utf8
ascii pur sucre
espace normal
espace_insecable (sans accent ;)
çédille latin1
ascii pur sucre
espace normal
espaceÂ_insecable (sans accent ;)
çédille UTF-8

# Remplacer la paire UTF-8
# (on pourrait taper  au lieu de xc2 ...)
~ $ sed -e 's/xc2xa0/_/g' texte texte_utf8
ascii pur sucre
espace normal
espace insecable (sans accent ;)
çédille latin1
ascii pur sucre
espace normal
espace_insecable (sans accent ;)
çédille UTF-8

# et pour traiter latin et utf8 ensemble,
~ $ sed -e 's/xc2?xa0/_/g' texte texte_utf8
ascii pur sucre
espace normal
espace_insecable (sans accent ;)
çédille latin1
ascii pur sucre
espace normal
espace_insecable (sans accent ;)
çédille UTF-8


--
Jacques L'helgoualc'h

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/DebFrFrenchLists
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact