Convertiți codarea binară pe care capul și Notepad-ul pot citi în UTF-8

Am un fișier CSV care este în set de caractere binare, dar trebuie să convertesc în UTF- 8 de procesat în HDFS (Hadoop).

Am folosit comanda de mai jos pentru a verifica setul de caractere.

file -bi filename.csv 

Ieșire:

application/octet-stream; charset=binary 

atunci când încerc să convertesc fișierul din binar în UTF-8 aruncă eroare.

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

poate cineva, vă rog, să mă ajutați să înțeleg este posibil să convertesc sau nu, pot vedea datele folosind comanda head.

Ce înseamnă, Binary înseamnă necitit, dar cum comanda principală sau notepad poate citi datele.

od -tc < filename.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 

Comentarii

  • Poți vă rugăm să adăugați rezultatul od -tc < yourfile.csv | head la întrebarea dvs.?
  • fișierul -bi arată caracterul său binar, Când verific din setul Vi codul de caractere arată utf-8.
  • Această ieșire od arată un fișier UTF-8 cu BOM. Pentru ca file să raporteze binar, trebuie să existe câteva caractere non-text (probabil cel puțin un octet NUL urmat de niște octeți non-NUL) înaintea aceleiași secțiuni.
  • Am eliminat toate " NUL " după ce fișierul -bi apare ca utf-8, Sper că eliminăm " NUL " nu va fi o problemă.

Răspuns

” binary „isn” t an encoding (nume set de caractere ). iconv are nevoie de un nume de codificare pentru a-și face treaba.

Utilitarul file nu oferă informații utile atunci când nu recunoaște formatul de fișier. ar putea fi UTF-16 de exemplu, fără un byte-encoding-mark (BOM). notepad citește acest lucru. Același lucru este valabil și pentru UTF-8 (și head va afișa asta deoarece terminalul dvs. poate fi setat t o codificare UTF-8 și nu i-ar păsa de o BOM).

Dacă fișierul este UTF-16, terminalul dvs. va afișa acest lucru folosind head deoarece majoritatea personajelor ar fi ASCII (sau chiar latin-1), făcând „celălalt” octet al caracterelor UTF-16 să fie nul.

În ambele cazuri, lipsa BOM va (în funcție de versiunea file) confundați-o. Dar alte programe pot funcționa, deoarece aceste formate de fișiere pot fi utilizate atât cu Microsoft Windows, cât și cu aplicații portabile care pot rula pe Windows.

Pentru a converti fișierul în UTF-8, trebuie să știți care este codarea acestuia utilizări și care este numele pentru codificarea respectivă cu iconv. Dacă este deja UTF-8, atunci dacă adăugați un BOM (la început) este opțional. UTF-16 are două arome, în funcție de care octetul este primul. Sau puteți chiar avea UTF-32. iconv -l enumeră aceste:

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” și „BE” se referă la capătul mic și capătul mare pentru ordinea de octeți. Windows utilizează aromele „LE” și iconv probabil presupune că pentru aromele lipsite de „LE” sau „BE”.

Puteți vedea acest lucru folosind 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 

Presupunând UTF-16LE, puteți converti folosind

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

Comentarii

  • Deci, cum pot converti fișierul în utf-8, intenția mea este să convertesc orice format (vine de la sursă) în utf-8.
  • @St é phaneChazelas, @ Thomas cum pot găsi codarea sursă, nu ' nu funcționează pentru utf- 32 (le / be) | 16 (le / be). Există vreo comandă pentru a găsi codarea fișierului sursă?
  • Așa cum s-a sugerat, afișarea unei descărcări octale ar ajuta cu sfaturi …
  • @St é phaneChazelas Cele de mai jos au funcționat, dar ce face " NUL " este bine să eliminați ?? pisică nume de fișier.csv | tr -d ' \ 000 ' > fișier out.csv -bi out.csv text / simplu; charset = utf-8
  • @WilliamR, acei octeți NUL din fișierul CSV sunt probabil o indicație a unei probleme mai largi, cum ar fi fișierul a fost corupt într-un fel, deoarece acestea nu sunt de așteptat în fișierul text și că ' este ceea ce ar trebui să te uiți. Uită-te unde apar în fișierul CSV (deși ar trebui să apară ca ^@ în vim) și vezi dacă datele din jurul acestuia sunt valide.

Răspuns

strings (de la binutils) reușește la ” tipăriți șirurile de caractere tipărite în fișiere „când atât iconv cât și recode au eșuat, de asemenea, cu file încă raportează conținutul ca date binare:

$ 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 

Comentarii

  • strings nu păstrează liniile goale. În afară de asta, face treaba.
  • @vulcanraven opțiunea -w (--include-all-whitespace) include linii noi și transport returnează,

Răspuns

https://pypi.python.org/pypi/chardet poate fi folosit pentru a determina codificarea textului dvs., apoi puteți converti de la acesta la ceea ce aveți nevoie.

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

În timp ce file -i tipărește

application/octet-stream; charset=binary 

chardet detectează corect

ascii with confidence 1.0 

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *