Por que não consigo converter UTF-8 em MS-ANSI usando iconv?

Por que não consigo converter UTF-8 em MS-ANSI usando iconv?

Estou tentando converter um arquivo de utf-8 para ms-ansi.

eu uso

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

mas pegue

  iconv: illegal input sequence at position 171359

ao olhar para isso

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

Eu entendi isso:

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

o arquivo não é utf-8 e, se não, o que devo usar com o iconv?

Responder1

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

Esse é um caractere (U+FEFF, codificado em 3 bytes em UTF-8) que também é usado como marca de ordem de bytes. De qualquer forma, esse caractere não é encontrado no MS-ANSI (um nome impróprio às vezes dado ao windows-1252, um superconjunto do iso8859-1), portanto não pode ser convertido para ele.

BOM são usados ​​(no início de algum texto) para diferenciar UTF16-LE de UTF16-BE (ou outras codificações não-byte afetadas pelo endianness da CPU). Não faz sentido em UTF-8, onde não há ambigüidade na ordem de bytes, faria ainda menos sentido no Windows-1252, que é um conjunto de caracteres de byte único. Como um "espaço sem quebra de largura zero", também é invisível e não possui propriedade de separação de palavras como o caractere "espaço de largura zero", portanto, provavelmente é seguro removê-lo completamente.

Com zsh, bashou ksh93:

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

Com algumas iconvimplementações, você também pode usar:

iconv -t windows-1252//translit < input

//translitrecorre a aproximações quando o texto não pode ser traduzido fielmente. Nesse caso, apenas remove o caractere 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

Outra opção poderia ser usar:

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

O primeiro iconvconverte para UTF-16 little-endian sem BOM, mas esse U + FEFF inicial o torna UTF-16 real com BOM, então o segundo iconvremove esse BOM conforme ele é usado para determinar a ordem de bytes dessa utf-16codificação.

informação relacionada