Aprenda a utilizar el comando iconv de Linux para convertir archivos a diferentes codificaciones de caracteres.
Los ordenadores almacenan los caracteres asignándolos a distintos valores binarios. Para visualizarlos correctamente, es necesario saber cómo se codificaron. El comando iconv convierte un archivo a una nueva codificación, gracias al artículo publicado en How to Geek.
Todo es binario
Independientemente del tipo de datos con los que trabaje o almacene un ordenador, se trata de información binaria. Imágenes, texto, música, vídeo y todo lo demás se almacena como datos binarios. Tanto si los datos están en un dispositivo de almacenamiento como si están cargados en la memoria del ordenador, siguen estando representados por valores binarios.
Puede leer también | Cómo gestionar el historial de comandos en Linux
Si los datos son texto y queremos mostrar ese texto en pantalla, hay que realizar una traducción para convertir los valores binarios en caracteres. Para realizar la traducción, necesitamos saber qué valores se utilizaron para representar cada carácter cuando se crearon los datos. El software puede entonces trabajar hacia atrás y volver a convertir los valores numéricos almacenados en caracteres.
Como el éxito depende de saber qué tipo de asignación se ha utilizado y de respetar rigurosamente las reglas de la asignación durante la creación y el uso de los datos, se han creado normas que formalizan dichas asignaciones de caracteres. Son fáciles de entender si entendemos bien la jerga.
Caracteres, bytes y mapeo
Un carácter es una letra, un número o cualquier otro símbolo visualizable, como los signos de puntuación, los signos matemáticos como igual "=" y más "+", y los símbolos monetarios. Lo que ves en pantalla representando esa letra se llama glifo, y un conjunto de glifos constituye un tipo de letra.
Puede leer también | Recomendaciones sobre secuencias de comandos Bash que pueden ahorrar tiempo en Linux
Un tipo de letra es lo que mucha gente llama erróneamente una fuente. En sentido estricto, un tipo de letra es una versión de un tipo de letra que se ha modificado, por ejemplo aumentando o disminuyendo su tamaño, o cambiando su peso para que las líneas de los glifos sean más gruesas o más finas. Independientemente del tipo de letra, la representación numérica del carácter sigue siendo la misma.
Todos los caracteres de una misma cartografía se denominan conjunto de caracteres. Cada carácter de un conjunto tiene su propio valor numérico, fijo y único, denominado punto de código. Si un carácter o símbolo no aparece en el juego de caracteres, es decir, no existe un punto de código para él, no puede mostrarse utilizando ese juego de caracteres. Una consideración importante es el número de bytes utilizados para representar un solo carácter. Cuantos más bytes se utilicen por carácter, más caracteres se podrán incluir en el juego.
Puede leer también | Cómo probar la velocidad de Internet desde la línea de comandos de Linux
El abuelito de todos los juegos de caracteres de un byte es el estándar ASCII. Data de finales de los años 60, cuando se estableció un estándar de 7 bits que codificaba 128 puntos de código diferentes para su uso en teleimpresoras. En cambio, el estándar Unicode contiene un total de 1.114.112 puntos de código. Se necesita un espacio de codificación tan grande porque Unicode intenta ofrecer soporte de mapeo de caracteres para todos los idiomas humanos.
Utilizar un número fijo de bytes para almacenar puntos de código es un despilfarro. Si un punto de código sólo necesita un byte para identificarlo, los demás bytes reservados para ese punto de código son redundantes. Los conjuntos de caracteres Unicode multibyte de longitud variable utilizan un número variable de bytes para los puntos de código, llegando a necesitar hasta cuatro bytes para describir un punto de código complicado.
Puede leer también | Cómo probar la velocidad de Internet desde la línea de comandos de Linux
Así, un punto de código puede tener que codificar dos tipos de datos. Por un lado, debe identificar el carácter que representa y, por otro, debe contener metadatos sobre sí mismo, como el número de bytes del punto de código. Además, algunos caracteres deben combinarse con otros para obtener el glifo final, por lo que el punto de código también debe codificar esa información.
Puede leer también | Razones para que la gente ame la línea de comandos de Linux
La ventaja de un esquema de longitud variable es que sólo se utilizan los bytes que realmente se necesitan. Esto es eficiente y da como resultado archivos más pequeños. La desventaja es que los datos son más complicados de leer y analizar. Y la conversión de un juego de caracteres a otro puede resultar muy difícil en muy poco tiempo.
Cómo utilizar el comando iconv
Lo que le falta al comando iconv en términos de opciones de línea de comandos lo compensa con creces en el número de codificaciones de caracteres que soporta. Enumera más de 1.100 codificaciones diferentes, pero muchas son alias para lo mismo. Podemos listar todas las codificaciones soportadas utilizando la opción -l (list).
iconv -l
Para utilizar iconv es necesario especificar un archivo fuente y un archivo de salida, así como la codificación desde la que se está convirtiendo y la codificación a la que se está convirtiendo. Si no especifica nombres de archivo, iconv utiliza STDIN y STDOUT, tomando su entrada de la línea de comandos y escribiendo su salida en la ventana del terminal. Puede canalizar la entrada a iconv, y también puede redirigir su salida a un archivo.
Utilizaremos iconv con STDIN para ilustrar algunos puntos. Necesitamos especificar la codificación del texto de entrada, así que usaremos el comando locale para descubrir cuál es.
locale
La primera línea dice que estamos utilizando el inglés de EE.UU. y la codificación Unicode UTF-8. Nuestra cadena de prueba contiene texto sin formato, una palabra acentuada, un carácter no inglés (el carácter alemán eszett, ß) y el símbolo monetario del euro.
plain àccented non-English ß Foreign currency €
Vamos a convertirlo a ASCII. Estamos usando echo para enviar nuestro texto de entrada a iconv. Estamos usando la opción -f (from) para especificar que la codificación de entrada es UTF-8, y la opción -t (to) para indicar que queremos la salida en US-ASCII.
Puede leer también | Comandos básicos más utilizados en GNU/Linux
Esto falla a la primera. No existe un carácter equivalente en US-ASCII para "à", por lo que se abandona la conversión. iconv utiliza el conteo de cero, por lo que se nos dice que el problema se produjo en la posición seis. Si añadimos la opción -c (continuar) iconv descartará los caracteres no convertibles y continuará procesando el resto de la entrada.
echo plain àccented non-English ß Foreign currency € | iconv -f UTF-8 -t US-ASCII
Ahora el comando se ejecuta hasta completarse, pero faltan caracteres en la salida. Podemos hacer que iconv proporcione una aproximación de un carácter no convertible sustituyéndolo por un carácter similar, u otra representación. Si no puede hacerlo, inserta un signo de interrogación "?" para que puedas ver fácilmente que un carácter no se ha convertido.
Este proceso se denomina transliteración, y para invocarlo hay que añadir la cadena "//TRANSLIT" a la codificación de destino.
echo plain àccented non-English ß Foreign currency € | iconv -f UTF-8 -t US-ASCII//TRANSLIT
Ahora tenemos un texto de salida completo, con "a" en lugar de "à" y "ss" en lugar de "ß", y "EUR" en lugar del símbolo de moneda "€".
Uso de iconv con archivos
Utilizar iconv con archivos es muy similar a utilizarlo en la línea de comandos. Para averiguar el tipo de codificación del archivo fuente, podemos utilizar el comando file.
file -i input.txt
Nuestro archivo de entrada está codificado en UTF-16LE. Es una codificación little-endian de 16 bits. Se ve así:
less input.txt
Si entrecierras los ojos y lees los caracteres en blanco, podrás distinguir las cadenas de texto reales. Muchos programas tratan incorrectamente un archivo como éste como binario, así que lo convertiremos a UTF-8.
Puede leer también | 10 divertidos línea de comandos de Linux que deberías probar cuando estés aburrido
Estamos utilizando la opción -f (from) para especificar la codificación del archivo de entrada, y la opción -t (to) para decirle a iconv que queremos la salida en UTF-8. Necesitamos usar la opción -o (output) para nombrar el archivo de salida. No utilizamos una opción para nombrar el archivo de entrada, sólo le decimos a iconv cómo se llama.
iconv -f UTF-16LE -t UTF-8//TRANSLIT input.txt -o output.txt
Nuestro archivo de salida tiene este aspecto:
less output.txt
Potencia cuando la necesitas
Puede que no utilices iconv con frecuencia, pero cuando lo necesitas, puede salvarte el pellejo.
Puede leer también | Comandos en GNU/Linux que no deberías usar
Recibo muchos archivos de personas que utilizan ordenadores Windows o Mac, y a menudo del extranjero. Llegan en todo tipo de codificaciones. He bendecido a iconv más de una vez por permitirme trabajar fácilmente con esos archivos en Linux.