Convierta la codificación binaria que el cabezal y el Bloc de notas pueden leer a UTF-8

Tengo un archivo CSV que está en un conjunto de caracteres binarios pero tengo que convertirlo a UTF- 8 para procesar en HDFS (Hadoop).

He usado el siguiente comando para verificar el conjunto de caracteres.

file -bi filename.csv 

Salida:

application/octet-stream; charset=binary 

cuando intento convertir el archivo de binario a UTF-8, arroja un error.

iconv -f binary -t utf-8 fiename.csv iconv: conversion from binary" is not supported Try iconv --help" or iconv --usage" for more information. 

¿Alguien puede ayudarme a entender si es posible convertir o no? Puedo ver los datos usando el comando head.

¿Qué significa, Binario significa no legible pero cómo comando principal o bloc de notas puede leer los datos.

od -tc < nombrearchivo.csv | head

0000000 357 273 277 | | R e q u e s t _ I D # 0000020 D # T y p e # D # S u b m i t t 0000040 e r # D # S h o r t _ D e s c r 0000060 i p t i o n # D # L o g _ T e x 0000100 t # D # S t a t u s # D # A s s 0000120 i g n e d _ T o # D # A s s i g 0000140 n e e # D # C r e a t e _ D a t 0000160 e # D # F o r w T o E x t H D # 0000200 D # L a s t _ M o d i f i e d _ 0000220 B y # D # L o g _ I D # D # L o 

Comentarios

  • ¿Puedes por favor agregue la salida de od -tc < yourfile.csv | head a su pregunta?
  • el archivo -bi muestra su carácter binario, cuando verifico desde Vi set characterencoding muestra utf-8.
  • Esa salida od muestra un archivo UTF-8 con BOM. Para que file informe binario, debe haber algunos caracteres que no sean de texto (probablemente al menos un byte NUL seguido de algunos bytes que no sean NUL) después de esa primera sección.
  • He eliminado todos los " NUL " después de que el archivo -bi se muestra como utf-8, espero eliminar " NUL " no será un problema.

Respuesta

» binario «no es» una codificación (nombre del conjunto de caracteres ). iconv necesita un nombre de codificación para hacer su trabajo.

La utilidad file no da información útil cuando no reconoce el formato del archivo. podría ser UTF-16 por ejemplo, sin una marca de codificación de bytes (BOM). notepad dice eso. Lo mismo se aplica a UTF-8 (y head mostrarían eso ya que su terminal puede estar configurado t o codificación UTF-8, y no le importaría una BOM).

Si el archivo es UTF-16, su terminal lo mostraría usando head porque la mayoría de los caracteres serían ASCII (o incluso Latin-1), lo que haría que el «otro» byte de los caracteres UTF-16 fuera nulo.

En cualquier caso, la falta de BOM (según la versión de file) lo confunden. Pero otros programas pueden funcionar, porque estos formatos de archivo se pueden usar con Microsoft Windows, así como con aplicaciones portátiles que pueden ejecutarse en Windows.

Para convertir el archivo a UTF-8, debe saber qué codificación usa y cuál es el nombre de esa codificación con iconv. Si ya es UTF-8, entonces si agrega una lista de materiales (al principio) es opcional. UTF-16 tiene dos sabores, según el byte primero. O podría incluso tener UTF-32. iconv -l enumera estos:

ISO-10646/UTF-8/ ISO-10646/UTF8/ UTF-7// UTF-8// UTF-16// UTF-16BE// UTF-16LE// UTF-32// UTF-32BE// UTF-32LE// UTF7// UTF8// UTF16// UTF16BE// UTF16LE// UTF32// UTF32BE// UTF32LE// 

«LE» y «BE» se refieren a pequeños y grandes para el orden de bytes. Windows usa los sabores «LE», y iconv probablemente asume eso para los sabores que carecen de «LE» o «BE».

Puedes ver esto usando un octal (sic) dump:

$ od -bc big-end 0000000 000 124 000 150 000 165 000 040 000 101 000 165 000 147 000 040 \0 T \0 h \0 u \0 \0 A \0 u \0 g \0 0000020 000 061 000 070 000 040 000 060 000 065 000 072 000 060 000 061 \0 1 \0 8 \0 \0 0 \0 5 \0 : \0 0 \0 1 0000040 000 072 000 065 000 067 000 040 000 105 000 104 000 124 000 040 \0 : \0 5 \0 7 \0 \0 E \0 D \0 T \0 0000060 000 062 000 060 000 061 000 066 000 012 \0 2 \0 0 \0 1 \0 6 \0 \n 0000072 $ od -bc little-end 0000000 124 000 150 000 165 000 040 000 101 000 165 000 147 000 040 000 T \0 h \0 u \0 \0 A \0 u \0 g \0 \0 0000020 061 000 070 000 040 000 060 000 065 000 072 000 060 000 061 000 1 \0 8 \0 \0 0 \0 5 \0 : \0 0 \0 1 \0 0000040 072 000 065 000 067 000 040 000 105 000 104 000 124 000 040 000 : \0 5 \0 7 \0 \0 E \0 D \0 T \0 \0 0000060 062 000 060 000 061 000 066 000 012 000 2 \0 0 \0 1 \0 6 \0 \n \0 0000072 

Suponiendo que UTF-16LE, podría convertir usando

iconv -f UTF-16LE// -t UTF-8// <input >output 

Comentarios

  • Entonces, ¿cómo puedo convertir el archivo a utf-8? Mi intención es convertir cualquier formato (que provenga de la fuente) a utf-8.
  • @St é phaneChazelas, @ Thomas ¿cómo puedo encontrar la codificación de mi fuente? No ' no funciona para utf- 32 (le / be) | 16 (le / ser). ¿Hay algún comando para encontrar la codificación del archivo fuente?
  • Como se sugirió, mostrar un volcado octal ayudaría con un consejo …
  • @St é phaneChazelas Lo siguiente funcionó, pero ¿qué " NUL " es bueno eliminarlo? cat filename.csv | tr -d ' \ 000 ' > archivo out.csv -bi out.csv Texto sin formato; charset = utf-8
  • @WilliamR, esos bytes NUL en su archivo csv son probablemente una indicación de un problema más amplio, como que el archivo se corrompió de alguna manera, ya que no se esperan en el archivo de texto, y que ' es lo que debería estar mirando. Mire dónde aparecen en el archivo csv (aunque debería mostrarse como ^@ en vim) y vea si los datos que lo rodean son válidos.

Respuesta

strings (de binutils) tiene éxito en » imprimir las cadenas de caracteres imprimibles en archivos «cuando también fallaron iconv y recode, con file sigue reportando el contenido como datos binarios:

$ file -i /tmp/textFile /tmp/textFile: application/octet-stream; charset=binary $ chardetect /tmp/textFile /tmp/textFile: utf-8 with confidence 0.99 $ iconv -f utf-8 -t utf-8 /tmp/textFile -o /tmp/textFile.iconv $ file -i /tmp/textFile.iconv /tmp/textFile.iconv: application/octet-stream; charset=binary $ cp /tmp/textFile /tmp/textFile.recode ; recode utf-8 /tmp/textFile.recode $ file -i /tmp/textFile.recode /tmp/textFile.recode: application/octet-stream; charset=binary $ strings /tmp/textFile > /tmp/textFile.strings $ file -i /tmp/textFile.strings /tmp/textFile.strings: text/plain; charset=us-ascii 

Comentarios

  • strings no conserva las líneas vacías. Aparte de eso, hace el trabajo.
  • @vulcanraven la opción -w (--include-all-whitespace) incluye nuevas líneas y carro devuelve,

Responder

https://pypi.python.org/pypi/chardet se puede usar para determinar la codificación de su texto, luego puede convertir de eso a lo que necesita.

 pip install chardet chardetect /my/path/to/file  

Mientras file -i imprime

application/octet-stream; charset=binary 

chardet detecta correctamente

ascii with confidence 1.0 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *