為什麼無法使用 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,以 UTF-8 的 3 個位元組編碼),也用作位元組順序標記。無論如何,在 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

第一個iconv轉換為不含 BOM 的 UTF-16 小端,但初始的 U+FEFF 使其成為帶有 BOM 的實際 UTF-16,因此第二個iconv會刪除該BOM,因為它用於確定該編碼的字節順序utf-16

相關內容