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 zsh
oder :bash
ksh93
sed $'s/\ufeff//g' < input | iconv -t windows-1252
Bei einigen iconv
Implementierungen können Sie auch Folgendes verwenden:
iconv -t windows-1252//translit < input
//translit
greift 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 iconv
konvertiert in UTF-16 Little-Endian ohne BOM, aber das anfängliche U+FEFF macht daraus tatsächlich UTF-16 mit BOM, sodass das zweite iconv
dieses BOM entfernt, da es verwendet wird, um die Byte-Reihenfolge dieser utf-16
Kodierung zu bestimmen.