バイナリ文字セットのCSVファイルがありますが、HDFS(Hadoop)で処理するにはUTF-8に変換する必要があります。
以下のコマンドを使用して、文字セットを確認しました。
file -bi filename.csv
出力:
application/octet-stream; charset=binary
ファイルをバイナリからUTF-8に変換しようとすると、エラーがスローされます。
iconv -f binary -t utf-8 fiename.csv
iconv: conversion from binary' is not supported
Try iconv --help' or iconv --usage' for more information.
誰かが私を理解するのを手伝ってくれませんか?.
それはどういう意味ですか、バイナリは読み取り不可を意味しますが、どのようにヘッドコマンドまたはメモ帳がデータを読み取ることができますか。
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
「バイナリ」はencoding(文字セット名)ではありません。 iconvが機能するには、エンコーディング名が必要です。
file
ユーティリティは、ファイル形式を認識しない場合、有用な情報を提供しません。たとえば、バイトエンコードマーク(BOM)がない場合はUTF-16
になります。 notepad
はそれを読み取ります。同じことがUTF-8
にも当てはまります(そしてhead
はthatと表示されます(端末がUTF-8エンコーディングに設定されている可能性があるため、そして、それはBOMを気にしません)。
ファイルがUTF-16の場合、ほとんどの文字はASCII(またはLatin-1))になるため、ターミナルはhead
を使用してそれを表示し、「その他」を作成しますUTF-16文字のバイトはnullです。
どちらの場合でも、BOMがないと(file
のバージョンによって)混乱します。ただし、これらのファイル形式は、Microsoft WindowsおよびWindows上で実行されるポータブルアプリケーションで使用できるため、他のプログラムも機能する可能性があります。
ファイルをUTF-8に変換するには、使用するエンコーディングと、そのエンコーディングの名前がiconv
で何であるかを知っている必要があります。すでにUTF-8の場合、BOMを(最初に)追加するかどうかはオプションです。 UTF-16には、最初のバイトに応じて2つのフレーバーがあります。または、evenでUTF-32にすることもできます。 iconv -l
はこれらをリストします:
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」と「BE」は、バイトオーダーのリトルエンドとビッグエンドを指します。 Windowsは「LE」フレーバーを使用しており、iconv
はおそらく「LE」または「BE」を欠くフレーバーを想定しています。
これは、8進(sic)ダンプを使用して確認できます。
$ 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
UTF-16LEを想定すると、次のように変換できます
iconv -f UTF-16LE// -t UTF-8// <input >output
strings
(binutilsから)は、iconv
とrecode
の両方が失敗しても、「ファイル内の印刷可能な文字の文字列を印刷する」ことに成功し、file
は引き続きレポートしますバイナリデータとしてのコンテンツ:
$ 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
https://pypi.python.org/pypi/chardet を使用してテキストのエンコーディングを決定し、それから必要なものに変換できます。