Hive INSERT OVERWRITE DIRECTORY命令输出未由分隔符分隔。为什么?

时间:2013-05-09 10:37:01

标签: hadoop hive

我正在加载的文件由''(空格)分隔。以下是文件。该文件位于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>现在,当我捕获文件时,字段不会被任何分隔符分隔: -

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版本。

10 个答案:

答案 0 :(得分:16)

问题是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 .

如上所述,带有空格。

答案 1 :(得分:10)

虽然问题已超过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

答案 2 :(得分:9)

我认为使用concat_ws函数可以实现输出;

  

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

这里我选择了逗号作为列分隔符

答案 3 :(得分:4)

我有不同的声音。

实际上,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 :(得分:3)

您可以在写入目录时提供分隔符

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

这应该适合你。

答案 5 :(得分:0)

默认分隔符为“^ A”。在python语言中,它是“\ x01”

当我想更改分隔符时,我使用SQL,如:

SELECT col1,delimiter,col2,delimiter,col3,..., 从表

然后,将 分隔符+“^ A” 视为新的分隔符。

答案 6 :(得分:0)

我怀疑蜂巢实际上是在写一个控制器-A作为分界仪,但当你在屏幕上做一只猫时,它并没有出现在你眼前。

相反,尝试在vi中调出文件或者如果你只是想看一点文件就把文件放到文件中,结果是:

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

vi my_local_file.txt

你应该能够在那里看到^ A字符。

答案 7 :(得分:0)

我遇到了这个问题,其中hive查询结果的输出应该是管道分隔的.. 运行此sed命令,您可以替换:^A to |

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

答案 8 :(得分:0)

这是一个更好的解决方案,我想虽然它是一个实现的方式。

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

答案 9 :(得分:0)

你可以使用这个参数“以'|'结尾的行格式分隔的字段”,例如你的情况应该是

INSERT OVERWRITE DIRECTORY'/ user / hadoop / output'行格式分隔的字段以'|'结尾SELECT * FROM graph_edges;