web-dev-qa-db-ja.com

Hive INSERT OVERWRITE DIRECTORYコマンドの出力は、区切り文字で区切られていません。どうして?

ロードしているファイルは、「」(空白)で区切られています。以下はファイルです。ファイルはHDFSにあります:

001 000
001 000
002 001
003 002
004 003
005 004
006 005
007 006
008 007
099 007

1>私は外部テーブルを作成し、以下のコマンドを発行してファイルをロードしています:

CREATE EXTERNAL TABLE IF NOT EXISTS graph_edges (src_node_id STRING COMMENT 'Node ID of Source node', dest_node_id STRING COMMENT 'Node ID of Destination node') ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS TEXTFILE LOCATION '/user/hadoop/input';

2>この後、次のコマンドを発行して、テーブルを別のファイルに挿入するだけです。

INSERT OVERWRITE DIRECTORY '/user/hadoop/output' SELECT * FROM graph_edges;

3>ここで、ファイルをcatすると、フィールドは区切り文字で区切られません。

hadoop dfs -cat /user/hadoop/output/000000_0

出力:-

001000
001000
002001
003002
004003
005004
006005
007006
008007
099007

誰かが私を助けてくれますか?なぜデリミタが削除され、出力ファイルを区切るのですか?

CREATE TABLEコマンドでDELIMITED BY '\t'を試しましたが、不要なNULL列が表示されています。

どんなポインタでも大歓迎です。 Hive 0.9.0バージョンを使用しています。

11
Anuroop

問題は、Hiveでは出力の区切り文字を指定できないことです- https://issues.Apache.org/jira/browse/Hive-634

解決策は、出力用の外部テーブルを作成し(区切り文字を指定)、ディレクトリの代わりに上書きテーブルを挿入することです。

-

HDFSに/user/hadoop/input/graph_edges.csvがあると仮定すると、

Hive> create external table graph_edges (src string, dest string) 
    > row format delimited 
    > fields terminated by ' ' 
    > lines terminated by '\n' 
    > stored as textfile location '/user/hadoop/input';

Hive> select * from graph_edges;
OK
001 000
001 000
002 001
003 002
004 003
005 004
006 005
007 006
008 007
099 007

Hive> create external table graph_out (src string, dest string) 
    > row format delimited 
    > fields terminated by ' ' 
    > lines terminated by '\n' 
    > stored as textfile location '/user/hadoop/output';

Hive> insert into table graph_out select * from graph_edges;
Hive> select * from graph_out;
OK
001 000
001 000
002 001
003 002
004 003
005 004
006 005
007 006
008 007
099 007

[user@box] hadoop fs -get /user/hadoop/output/000000_0 .

上記のように、スペースが戻ってきます。

17
kgu87

質問は2年以上前のものであり、トップの答えはその時点では正しかったのですが、現在、Hiveに区切りデータをディレクトリに書き込むように指示することが可能です。

従来の^ Aセパレータを使用してデータを出力する例を次に示します。

INSERT OVERWRITE DIRECTORY '/output/data_delimited'
SELECT *
FROM data_schema.data_table

そして今、タブ区切り文字があります:

INSERT OVERWRITE DIRECTORY '/output/data_delimited'
row format delimited 
FIELDS TERMINATED BY '\t'
SELECT *
FROM data_schema.data_table
10
Garren S

Concat_ws関数を使用すると、出力を達成できると思います。

INSERT OVERWRITE DIRECTORY '/ user/hadoop/output' SELECT concat_ws( '、'、col1、col2)FROM graph_edges;

ここで、列の区切り文字としてコンマを選択しました

10
Sid

いくつかの異なる声があります。

実際、Hiveはカスタム区切り文字をサポートしていません。

ただし、INSERT OVERWRITE DIRECTORYを使用すると、行に区切り文字が含まれます。区切り文字は'\1'です。

hadoop dfs -cat $file | head -1 | xxdを使用してそれを見つけるか、HDFSからローカルマシンにファイルを取得してvimで開くことができます。 vimには区切り文字である「^ A」のような文字が含まれます。

質問に戻って、簡単な方法で解決できます。

  1. それでもINSERT OVERWRITE DIRECTORY '/user/hadoop/output'を使用して/user/hadoop/outputを生成します。

  2. '\1'で区切られたフィールドを持つ外部テーブルを作成します。

    create external table graph_out (src string, dest string) 
    row format delimited 
    fields terminated by '\1' 
    lines terminated by '\n' 
    stored as textfile location '/user/hadoop/output';
    
4
pensz

ディレクトリに書き込むときに区切り文字を指定できます

INSERT OVERWRITE DIRECTORY '/user/hadoop/output'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY
SELECT * FROM graph_edges;

これはあなたのために働くはずです。

3
user3886907

Hiveクエリの結果の出力をパイプで区切る必要があるという問題がありました。このsedコマンドを実行すると、次のように置き換えられます:^A to |

sed 's#\x01#|#g' test.log > piped_test.log

1
user3798061

このパラメーターを使用できます"'|'で終了する行フォーマット区切りフィールド"たとえば、あなたの場合

INSERT OVERWRITE DIRECTORY '/ user/hadoop/output'行形式で区切られたフィールドは '|'で終了しますSELECT * FROM graph_edges;

0
Miguel Angel

Hiveが実際にコントロールAをデリミターとして書いているのではないかと疑っていますが、画面に猫を乗せても目には現れません。

代わりに、viでファイルを表示するか、ファイルの一部のみを表示したい場合はファイルの先頭に移動して、結果をviにします。

hadoop dfs -cat/user/hadoop/output/000000_0 | head> my_local_file.txt

vi my_local_file.txt

そこに^ A文字が表示されるはずです。

0
user3267919

これは達成方法についてのラウンドですが、これは私が思うより良い解決策でしょう。

INSERT OVERWRITE DIRECTORY '/ user/hadoop/output' SELECT src_node_id、 ''、dest_node_id FROM graph_edges;

0
bkd

デフォルトのセパレータは"^ A"です。 python言語、それは"\ x01"です。

区切り文字を変更するときは、次のようなSQLを使用します。

SELECT col1、delimiter、col2、delimiter、col3、...、FROMテーブル

次に、delimiter + "^ A"を新しい区切り文字と見なします。

0
moshaholo