iconvを使用してUTF-8をMS-ANSIに変換できないのはなぜですか?

iconvを使用してUTF-8をMS-ANSIに変換できないのはなぜですか?

utf-8からms-ansiにファイルを変換しようとしています。

私は使う

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

しかし得る

  iconv: illegal input sequence at position 171359

これを調べるとき

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

わかりました:

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

ファイルがutf-8ではありません。それ以外の場合は、代わりにiconvを使用する必要がありますか?

答え1

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

これは、バイト順表示としても使用される文字(U + FEFF、3バイトUTF-8でエンコードされています)です。いずれにせよ、その文字はMS-ANSIに見つからないため(windows-1252(iso8859-1の親セット)で誤った名前が指定されているため)、その文字に変換できません。

BOMは、UTF16-LEとUTF16-BE(またはCPUエンディアンの影響を受ける他のバイト単位のエンコード)を区別するために、一部のテキストの先頭に使用されます。バイトオーダーのあいまいさのないUTF-8では意味がなく、シングルバイト文字セットのwindows-1252ではさらにそうです。 「幅がゼロの空白」なので表示されず、「ゼロ幅の空白」文字のように単語を区切る属性がないため、完全に削除するのは安全です。

zsh、またはbashksh93

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

一部のiconv実装では、次のものも使用できます。

iconv -t windows-1252//translit < input

//translitテキストを忠実に翻訳できない場合は、近似値を使用してください。この場合、U + FEFF文字のみが削除されます。

$ 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

別のオプションは、次のものを使用することです。

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

最初はiconvBOMなしのUTF-16リトルエンディアンに変換されますが、最初のU + FEFFはBOMを持つ実際のUTF-16に変換され、2番目はiconvセクション順序という単語のエンコードを決定するために使用されるため、そのBOMを削除しますutf-16

関連情報