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 zsh
o :bash
ksh93
sed $'s/\ufeff//g' < input | iconv -t windows-1252
Con algunas iconv
implementaciones, también puedes usar:
iconv -t windows-1252//translit < input
//translit
recurre 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 iconv
se 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 iconv
elimina esa BOM a medida que se usa para determinar el orden de bytes de esa utf-16
codificación.