ファイルを 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、UTF-8 で 3 バイトにエンコード) です。いずれにしても、その文字は MS-ANSI (iso8859-1 のスーパーセットである windows-1252 に付けられる不適切な名前) にはないため、変換できません。
BOM は、UTF16-LE と UTF16-BE (または CPU エンディアンネスの影響を受けるその他の非バイト エンコーディング) を区別するために (一部のテキストの先頭で) 使用されます。バイト順序の曖昧さがない UTF-8 では意味がありません。シングル バイト文字の文字セットである windows-1252 ではさらに意味がありません。「ゼロ幅のノーブレーク スペース」であるため、これは非表示であり、「ゼロ幅のスペース」文字のような単語の区切りプロパティもないため、完全に削除しても安全です。
zsh
、または:bash
ksh93
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
最初のiconv
変換は BOM なしの UTF-16 リトルエンディアンに変換されますが、最初の U+FEFF によって実際の UTF-16 は BOM 付きになります。そのため、2 番目のiconv
変換では、そのエンコードのバイト順序を決定するために使用される BOM が削除されますutf-16
。