Konwertuj kodowanie binarne, które głowica i Notatnik mogą odczytać do UTF-8

Mam plik CSV, który jest w zestawie znaków binarnych, ale muszę przekonwertować na UTF- 8 do przetwarzania w HDFS (Hadoop).

Użyłem poniższego polecenia, aby sprawdzić zestaw znaków.

file -bi filename.csv 

Wynik:

application/octet-stream; charset=binary 

kiedy próbuję przekonwertować plik z formatu binarnego na UTF-8, generuje błąd.

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

czy ktoś może mi pomóc zrozumieć, czy można konwertować, czy nie, mogę zobaczyć dane za pomocą polecenia head.

Co to znaczy, binarny oznacza nieczytelny, ale jak polecenie head lub notatnik może odczytać dane.

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 

Komentarze

  • Czy możesz proszę dodać wynik od -tc < yourfile.csv | head do swojego pytania?
  • plik -bi pokazuje swój znak binarny, Kiedy sprawdzam z Vi, ustaw characterencoding pokazuje utf-8.
  • To od wyjście pokazuje plik UTF-8 z BOM. Aby file raportował dane binarne, poza pierwszą sekcją musi znajdować się kilka znaków nietekstowych (prawdopodobnie przynajmniej jeden bajt NUL, po którym następują bajty inne niż NUL).
  • Usunąłem wszystkie " NUL " po tym, jak ten plik -bi wyświetla się jako utf-8. Mam nadzieję, że usunąłem " NUL " nie będzie problemem.

Odpowiedź

” binarne „isn” t an kodowanie (nazwa zestawu znaków ). iconv wymaga nazwy kodowania, aby wykonać swoje zadanie.

Narzędzie file nie podaje przydatnych informacji, jeśli nie rozpoznaje formatu pliku. może być na przykład UTF-16 bez znaku kodowania bajtów (BOM). notepad to czyta. To samo dotyczy UTF-8 (a head wyświetli to , ponieważ twój terminal może być ustawiony t o kodowanie UTF-8, i nie obchodzi go BOM).

Jeśli plik jest w formacie UTF-16, terminal wyświetli to używając head, ponieważ większość znaków byłaby ASCII (lub nawet Latin-1), czyniąc „inny” bajt znaków UTF-16 wartością zerową.

W każdym przypadku brak BOM (w zależności od wersja file) to mylić. Ale inne programy mogą działać, ponieważ te formaty plików mogą być używane w systemie Microsoft Windows, a także w aplikacjach przenośnych, które mogą działać w systemie Windows.

Aby przekonwertować plik do UTF-8, musisz wiedzieć, jakie kodowanie go używa i jaka jest nazwa tego kodowania z iconv. Jeśli jest to już UTF-8, to dodanie BOM-u (na początku) jest opcjonalne. UTF-16 ma dwa smaki, według których bajt jest pierwszy. Lub możesz nawet mieć UTF-32. iconv -l zawiera następującą listę:

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” odnoszą się do małych i dużych dla kolejności bajtów. Windows używa odmian „LE” i iconv prawdopodobnie zakłada, że dla odmian bez „LE” lub „BE”.

Możesz to zobaczyć używając ósemkowego (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 

Zakładając UTF-16LE, możesz konwertować używając

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

Komentarze

  • Jak więc mogę przekonwertować plik na utf-8, moim zamiarem jest przekonwertowanie dowolnego formatu (pochodzącego ze źródła) na utf-8.
  • @St é phaneChazelas, @ Thomas jak mogę znaleźć moje kodowanie źródłowe, to nie ' nie działa dla utf- 32 (le / be) | 16 (le / be). Czy jest jakieś polecenie znalezienia kodowania pliku źródłowego?
  • Jak sugerowano, pokazanie zrzutu ósemkowego pomogłoby w uzyskaniu porady …
  • @St é phaneChazelas Poniższe działało, ale co " NUL " czy dobrze jest usunąć? cat nazwa_pliku.csv | tr -d ' \ 000 ' > out.csv file -bi out.csv Zwykły tekst; charset = utf-8
  • @WilliamR, te bajty NUL w twoim pliku csv prawdopodobnie wskazują na szerszy problem, taki jak plik został w jakiś sposób uszkodzony, ponieważ nie są one oczekiwane w pliku tekstowym i że ' to jest to, na co powinieneś patrzeć. Spójrz, gdzie pojawiają się w pliku csv (chociaż powinny być wyświetlane jako ^@ w vimie) i zobacz, czy dane wokół niego są prawidłowe.

Odpowiedź

strings (z binutils) powiodło się „ wypisuje ciągi drukowalnych znaków w plikach „, gdy zarówno iconv, jak i recode również nie powiodły się, z file nadal zgłasza zawartość jako dane binarne:

$ 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 

Komentarze

  • nie zachowuje pustych wierszy. Poza tym spełnia swoje zadanie.
  • @vulcanraven opcja -w (--include-all-whitespace) obejmuje nowe linie i karetkę zwraca,

Odpowiedź

https://pypi.python.org/pypi/chardet może być użyty do określenia kodowania twojego tekstu, a następnie możesz przekonwertować go na to, czego potrzebujesz.

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

Podczas gdy file -i drukuje

application/octet-stream; charset=binary 

chardet poprawnie wykrywa

ascii with confidence 1.0 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *