Convertir UTF8 en UTF16 en utilisant iconv

quand j'utilise iconv pour passer de UTF16 à UTF8 alors tout va bien mais vice versa ça ne marche pas. J'ai les fichiers suivants:

a-16.strings:    Little-endian UTF-16 Unicode c program text
a-8.strings:     UTF-8 Unicode c program text, with very long lines

le texte semble correct dans l'éditeur. Lorsque je l'exécute:

iconv -f UTF-8 -t UTF-16LE a-8.strings > b-16.strings

Puis-je obtenir ce résultat:

b-16.strings:    data
a-16.strings:    Little-endian UTF-16 Unicode c program text
a-8.strings:     UTF-8 Unicode c program text, with very long lines

file utilitaire n'affiche pas le format de fichier prévu et le texte ne semble pas bon dans l'éditeur non plus. Se pourrait-il qu'iconv ne crée pas un bon BOM? Je l'exécute sur la ligne de commande MAC.

Pourquoi pas le b-16 au format UTF-16LE? Y a-t-il une autre façon de convertir utf8 en utf16?

plus d'élaboration est ci-dessous.

$ iconv -f UTF-8 -t UTF-16LE a-8.strings > b-16le-BAD-fromUTF8.strings
$ iconv -f UTF-8 -t UTF-16 a-8.strings > b-16be.strings 
$ iconv -f UTF-16 -t UTF-16LE b-16be.strings > b-16le-BAD-fromUTF16BE.strings

$ file *s
a-16.strings:                   Little-endian UTF-16 Unicode c program text, with very long lines
a-8.strings:                    UTF-8 Unicode c program text, with very long lines
b-16be.strings:                 Big-endian UTF-16 Unicode c program text, with very long lines
b-16le-BAD-fromUTF16BE.strings: data
b-16le-BAD-fromUTF8.strings:    data


$ od -c a-16.strings | head
0000000  377 376   /     *          f 001   E     S     K  

$ od -c a-8.strings | head 
0000000    /   *   *   *       Č  **   E   S   K   Y       (   J   V   O

$ od -c b-16be.strings | head
0000000  376 377     /     *     *     *       001  f     E

$ od -c b-16le-BAD-fromUTF16BE.strings | head                                
0000000    /     *     *     *          f 001   E     S  

$ od -c b-16le-BAD-fromUTF8.strings | head
0000000    /     *     *     *          f 001   E     S  

il est clair que le BOM est absent chaque fois que j'exécute la conversion en UTF-16LE. Toute aide à ce sujet?

22
demandé sur PerfectGamesOnline.com 2012-01-19 13:43:36

3 réponses

UTF-16LE dit iconv pour générer little-endian UTF-16 sans a BOM (Byte Order Mark). Apparemment, il suppose que puisque vous avez spécifié LE, le BOM n'est pas nécessaire.

UTF-16 lui dit de générer du texte UTF-16 (dans l'ordre des octets de la machine locale) une NOMENCLATURE.

Si vous êtes sur un little-endian machine, je ne vois pas un moyen de dire iconv pour générer L'UTF-16 big-endian avec un BOM, mais je pourrais juste manquer quelque.

je trouve que le file la commande ne reconnaît pas le texte UTF-16 sans BOM, et votre éditeur pourrait ne pas l'être non plus. Mais si vous exécutez iconv -f UTF-16LE -t UTF_8 b-16 strings, vous devriez obtenir une version UTF-8 valide du fichier original.

essayez de courir od -c sur les fichiers pour voir leur contenu réel.

mise à jour:

on dirait que vous êtes sur une machine big-endian (x86 est little-endian), et vous essayez de générer un petit-endian UTF-16 file avec un BOM. Est-ce exact? Aussi loin que je peux dire, iconv ne pas le faire directement. Mais cela devrait fonctionner:

( printf "\xff\xfe" ; iconv -f utf-8 -t utf-16le UTF-8-FILE ) > UTF-16-FILE

Le comportement de l' printf dépend de vos paramètres régionaux; j'ai LANG=en_US.UTF-8.

(quelqu'un Peut-il suggérer une solution plus élégante?)

une Autre solution, si vous connaissez le boutisme de la sortie produite par -t utf-16:

iconv -f utf-8 -t utf-16 UTF-8-FILE | dd conv=swab 2>/dev/null
31
répondu Keith Thompson 2012-09-17 19:12:34

j'ai d'abord convertir UTF-16, qui ajoute une marque d'ordre d'octet, si nécessaire comme le mentionne Keith Thompson. Alors, puisque UTF-16 ne pas définir l'endianness, nous devons utiliser file pour déterminer si elle est UTF-16BE ou UTF-16LE. Enfin, nous pouvons convertir à UTF-16LE.

iconv -f utf-8 -t utf-16 UTF-8-FILE > UTF-16-UNKNOWN-ENDIANNESS-FILE
FILE_ENCODING="$( file --brief --mime-encoding UTF-16-UNKNOWN-ENDIANNESS-FILE )"
iconv -f "$FILE_ENCODING" -t UTF-16LE UTF-16-UNKNOWN-ENDIANNESS-FILE > UTF-16-FILE
3
répondu Heath Borders 2017-05-23 11:47:15

ce n'est peut-être pas une solution élégante mais j'ai trouvé un moyen manuel pour assurer la conversion correcte pour mon problème qui je crois est similaire au sujet de ce fil.

Le Problème: J'ai reçu un fichier texte d'un utilisateur et j'allais le traiter sur Linux (en particulier Ubuntu) en utilisant le script shell (tokenisation, splitting, etc.). Appelons le fichier myfile.txt. La première indication que j'ai obtenu que quelque chose était mal était que la tokenization n'était pas travailler. Donc, je n'ai pas été surpris quand j'ai couru le file commande myfile.txt et le suivant

$ file myfile.txt

myfile.txt: Little-endian UTF-16 Unicode text, with very long lines, with CRLF line terminators

si le fichier était conforme, voici ce qui aurait dû être la conversation:

$ file myfile.txt

myfile.txt: ASCII text, with very long lines

La Solution: Pour rendre le fichier conforme, voici les 3 étapes manuelles que j'ai trouvées pour travailler après quelques essais et erreurs avec d'autres étapes.

  1. première conversion en Big Endian au même encodage via vi (ou vim). vi myfile.txt. vi:set fileencoding=UTF-16BE alors écrivez le fichier. Vous pourriez avoir à forcer avec :!wq.

  2. vi myfile.txt (qui devrait maintenant être en utf-16BE). vi:set fileencoding=ASCII alors écrivez le fichier. Encore une fois, vous devrez peut-être forcer l'écriture avec !wq.

  3. Exécuter dos2unix convertisseur:d2u myfile.txt. Maintenant, si vous exécutez file myfile.txt vous devriez maintenant voir une sortie ou quelque chose de plus familier et d'assurer comme:

    myfile.txt: ASCII text, with very long lines
    

C'est ça. C'est ce qui a fonctionné pour moi, et j'ai ensuite été capable d'exécuter mon script bash shell de traitement de myfile.txt. J'ai constaté que je ne pouvais pas sauter l'Étape 2. C'est, dans ce cas je ne peut pas passer directement à l'Étape 3. Espérons que vous trouverez cette information utile; espérons que quelqu'un pourra l'automatiser peut-être via sed ou similaires. Acclamation.

0
répondu Adams 2016-02-26 18:00:17