¿Por qué no puedo convertir un UTF-8 a MS-ANSI usando iconv?

¿Por qué no puedo convertir un UTF-8 a MS-ANSI usando iconv?

Estoy intentando convertir un archivo de utf-8 a ms-ansi.

yo suelo

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

pero consigue

  iconv: illegal input sequence at position 171359

al mirar esto

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

Entiendo esto:

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

¿El archivo no es utf-8? Si no, ¿qué debo usar en su lugar con iconv?

Respuesta1

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

Se trata de un carácter (U+FEFF, codificado en 3 bytes en UTF-8) que también se utiliza como marca de orden de bytes. En cualquier caso, ese carácter no se encuentra en MS-ANSI (un nombre inadecuado que a veces se le da a Windows-1252, un superconjunto de iso8859-1), por lo que no se puede convertir a ese.

Las BOM se utilizan (al comienzo de algún texto) para diferenciar UTF16-LE de UTF16-BE (u otras codificaciones que no son de bytes afectadas por el endianismo de la CPU). No tiene sentido en UTF-8 donde no hay ambigüedad en el orden de los bytes; tendría aún menos sentido en Windows-1252, que es un juego de caracteres de un solo byte. Como "espacio sin separación de ancho cero", también es invisible y no tiene ninguna propiedad de separación de palabras como la que tendría el carácter de "espacio de ancho cero", por lo que probablemente sea seguro eliminarlo por completo.

Con zsho :bashksh93

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

Con algunas iconvimplementaciones, también puedes usar:

iconv -t windows-1252//translit < input

//translitrecurre a aproximaciones cuando el texto no puede traducirse fielmente. En ese caso, simplemente elimina el carácter 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

Otra opción podría ser utilizar:

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

El primero iconvse convierte a UTF-16 little-endian sin BOM, pero ese U+FEFF inicial lo convierte en UTF-16 real con BOM, por lo que el segundo iconvelimina esa BOM a medida que se usa para determinar el orden de bytes de esa utf-16codificación.

información relacionada