utf8 txt texto subtitulos saber online convertir como codificacion cambiar bom archivos archivo linux macos unicode command-line

linux - txt - convertir texto a utf-8 online



Convertir UTF8 a UTF16 usando iconv (3)

Primero convierto a UTF-16 , que antepondrá una marca de orden de bytes, si es necesario, como menciona Keith Thompson . Luego, dado que UTF-16 no define la endianidad, debemos usar el file para determinar si es UTF-16BE o UTF-16LE . Finalmente, podemos convertir a UTF-16LE .

iconv -f utf-8 -t utf-16 UTF-8-FILE > UTF-16-UNKNOWN-ENDIANNESS-FILE FILE_ENCODING="$( file --brief --mime-encoding UTF-16-UNKNOWN-ENDIANNESS-FILE )" iconv -f "$FILE_ENCODING" -t UTF-16LE UTF-16-UNKNOWN-ENDIANNESS-FILE > UTF-16-FILE

Cuando uso iconv para convertir de UTF16 a UTF8, entonces todo está bien, pero viceversa, no funciona. Tengo estos archivos:

a-16.strings: Little-endian UTF-16 Unicode c program text a-8.strings: UTF-8 Unicode c program text, with very long lines

El texto se ve bien en el editor. Cuando corro esto:

iconv -f UTF-8 -t UTF-16LE a-8.strings > b-16.strings

Entonces me sale este resultado:

b-16.strings: data a-16.strings: Little-endian UTF-16 Unicode c program text a-8.strings: UTF-8 Unicode c program text, with very long lines

La utilidad de file no muestra el formato de archivo esperado y el texto tampoco se ve bien en el editor. ¿Podría ser que iconv no crea una lista de materiales adecuada? Lo ejecuto en la línea de comandos de MAC.

¿Por qué el b-16 no está en el formato UTF-16LE adecuado? ¿Hay otra manera de convertir utf8 a utf16?

Más elaboración está abajo.

$ iconv -f UTF-8 -t UTF-16LE a-8.strings > b-16le-BAD-fromUTF8.strings $ iconv -f UTF-8 -t UTF-16 a-8.strings > b-16be.strings $ iconv -f UTF-16 -t UTF-16LE b-16be.strings > b-16le-BAD-fromUTF16BE.strings $ file *s a-16.strings: Little-endian UTF-16 Unicode c program text, with very long lines a-8.strings: UTF-8 Unicode c program text, with very long lines b-16be.strings: Big-endian UTF-16 Unicode c program text, with very long lines b-16le-BAD-fromUTF16BE.strings: data b-16le-BAD-fromUTF8.strings: data $ od -c a-16.strings | head 0000000 377 376 / /0 * /0 /0 /f 001 E /0 S /0 K /0 $ od -c a-8.strings | head 0000000 / * * * Č ** E S K Y ( J V O $ od -c b-16be.strings | head 0000000 376 377 /0 / /0 * /0 * /0 * /0 001 /f /0 E $ od -c b-16le-BAD-fromUTF16BE.strings | head 0000000 / /0 * /0 * /0 * /0 /0 /f 001 E /0 S /0 $ od -c b-16le-BAD-fromUTF8.strings | head 0000000 / /0 * /0 * /0 * /0 /0 /f 001 E /0 S /0

Está claro que falta la lista de materiales cuando ejecuto la conversión a UTF-16LE. ¿Alguna ayuda en esto?


Puede que esta no sea una solución elegante, pero encontré una forma manual para asegurar la conversión correcta para mi problema que creo que es similar al tema de este hilo.

El problema: obtuve un archivo de datos de texto de un usuario y lo iba a procesar en Linux (específicamente, Ubuntu) usando un script de shell (tokenización, división, etc.). Llamemos al archivo myfile.txt . La primera indicación de que entendí que algo estaba mal era que la tokenización no estaba funcionando. Así que no me sorprendió cuando ejecuté el comando de file en myfile.txt y obtuve lo siguiente

$ file myfile.txt myfile.txt: Little-endian UTF-16 Unicode text, with very long lines, with CRLF line terminators

Si el archivo era compatible, esto es lo que debería haber sido la conversación:

$ file myfile.txt myfile.txt: ASCII text, with very long lines

La solución: para hacer que el archivo de datos sea compatible, a continuación se encuentran los 3 pasos manuales que encontré para funcionar después de algunas pruebas y errores con otros pasos.

  1. Primero convierta a Big Endian en la misma codificación a través de vi (o vim ). vi myfile.txt . En vi do :set fileencoding=UTF-16BE luego escriba el archivo. Puede que tenga que forzarlo con :!wq .

  2. vi myfile.txt (que ahora debería estar en utf-16BE). En vi do :set fileencoding=ASCII luego escriba el archivo. De nuevo, puede que tengas que forzar la escritura con !wq .

  3. Ejecute el convertidor dos2unix : d2u myfile.txt . Si ahora ejecuta el file myfile.txt , ahora debería ver una salida o algo más familiar y seguro como:

    myfile.txt: ASCII text, with very long lines

Eso es. Eso fue lo que funcionó para mí, y luego pude ejecutar mi script bash de procesamiento de myfile.txt . Descubrí que no puedo omitir el Paso 2. Es decir, en este caso no puedo saltar directamente al Paso 3. Esperamos que esta información sea útil; Esperemos que alguien pueda automatizarlo quizás a través de sed o similar. Aclamaciones.


UTF-16LE le dice a iconv que genere un little endian UTF-16 sin una lista de materiales (marca de orden de bytes). Aparentemente asume que, dado que especificó LE , la lista de materiales no es necesaria.

UTF-16 le dice que genere texto UTF-16 (en el orden de bytes de la máquina local) con una lista de materiales.

Si estás en una máquina little-endian, no veo una manera de decirle a iconv que genere un UTF-16 big-endian con un BOM, pero es posible que solo me esté perdiendo algo.

Me parece que el comando de file no reconoce el texto UTF-16 sin una lista de materiales, y su editor tampoco puede. Pero si ejecuta iconv -f UTF-16LE -t UTF_8 b-16 strings , debe obtener una versión válida de UTF-8 del archivo original.

Intente ejecutar od -c en los archivos para ver su contenido real.

ACTUALIZACIÓN:

Parece que estás en una máquina big-endian (x86 es little-endian), e intentas generar un archivo UTF-16 little-endian con una lista de materiales. ¿Es eso correcto? Por lo que puedo decir, iconv no lo hará directamente. Pero esto debería funcionar:

( printf "/xff/xfe" ; iconv -f utf-8 -t utf-16le UTF-8-FILE ) > UTF-16-FILE

El comportamiento de printf puede depender de su configuración regional; Tengo LANG=en_US.UTF-8 .

(¿Alguien puede sugerir una solución más elegante?)

Otra solución, si conoce el carácter endiano de la salida producida por -t utf-16 :

iconv -f utf-8 -t utf-16 UTF-8-FILE | dd conv=swab 2>/dev/null