为什么无法使用 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

相关内容