我正在嘗試將文件從 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
,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 使其成為帶有 BOM 的實際 UTF-16,因此第二個iconv
會刪除該BOM,因為它用於確定該編碼的字節順序utf-16
。