Warum kann ich UTF-8 mit iconv nicht in MS-ANSI konvertieren?

Warum kann ich UTF-8 mit iconv nicht in MS-ANSI konvertieren?

Ich versuche, eine Datei von UTF-8 in MS-ANSI zu konvertieren.

ich benutze

  iconv -f UTF8 -t MS-ANSI// < data.txt

aber bekommen

  iconv: illegal input sequence at position 171359

wenn man sich das ansieht

 dd if=data.txt of=error.txt bs=1 count=10 skip=171359

Ich bekomme Folgendes:

 hexdump -C error.txt
 00000000  ef bb bf 38 3a 6e 61 09  38 3a                    |...8:na.8:|
 0000000a

ist die Datei nicht UTF-8, und wenn nicht, was sollte ich stattdessen mit Iconv verwenden?

Antwort1

$ printf '\xef\xbb\xbf' | uconv -x any-name
\N{ZERO WIDTH NO-BREAK SPACE}

Das ist ein Zeichen (U+FEFF, in 3 Bytes in UTF-8 kodiert), das auch als Byte-Order-Mark verwendet wird. Dieses Zeichen ist jedenfalls nicht in MS-ANSI enthalten (ein unpassender Name, der manchmal für Windows-1252, eine Obermenge von ISO8859-1, verwendet wird) und kann daher nicht dorthin konvertiert werden.

BOM werden (am Anfang eines Textes) verwendet, um UTF16-LE von UTF16-BE (oder anderen nicht-Byte-Kodierungen, die von der Byte-Reihenfolge der CPU betroffen sind) zu unterscheiden. Es ergibt keinen Sinn in UTF-8, wo es keine Mehrdeutigkeit in der Byte-Reihenfolge gibt, und es würde noch weniger Sinn ergeben in Windows-1252, einem Zeichensatz mit einem einzelnen Byte. Als „Leerzeichen ohne Umbruch“ ist es außerdem unsichtbar und hat keine Worttrennungseigenschaft wie das „Leerzeichen mit Breite Null“, daher ist es wahrscheinlich sicher, es ganz zu entfernen.

Mit zshoder :bashksh93

sed $'s/\ufeff//g' < input | iconv -t windows-1252

Bei einigen iconvImplementierungen können Sie auch Folgendes verwenden:

iconv -t windows-1252//translit < input

//translitgreift auf Annäherungen zurück, wenn der Text nicht originalgetreu übersetzt werden kann. In diesem Fall wird einfach das Zeichen U+FEFF entfernt.

$ printf '\xef\xbb\xbf\x38\x3a\x6e\x61\x09\x38\x3a' |
    iconv -t windows-1252//translit | hd
00000000  38 3a 6e 61 09 38 3a                              |8:na.8:|
00000007

Eine weitere Möglichkeit wäre, Folgendes zu verwenden:

iconv -t utf-16le | iconv -f utf-16 -t windows-1252

Das erste iconvkonvertiert in UTF-16 Little-Endian ohne BOM, aber das anfängliche U+FEFF macht daraus tatsächlich UTF-16 mit BOM, sodass das zweite iconvdieses BOM entfernt, da es verwendet wird, um die Byte-Reihenfolge dieser utf-16Kodierung zu bestimmen.

verwandte Informationen