Hadoop 配置单元插入覆盖目录命令输出未用分隔符分隔。为什么?

Hadoop 配置单元插入覆盖目录命令输出未用分隔符分隔。为什么?,hadoop,hive,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', des

我正在加载的文件由“”空格分隔。下面是文件。该文件位于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';
INSERT OVERWRITE DIRECTORY '/user/hadoop/output' SELECT * FROM graph_edges;
2> 在此之后,我只需通过发出以下命令将表插入另一个文件中:-

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';
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命令中,我尝试用“\t”分隔,但是得到了不必要的NULL列


任何指点都很有用。我正在使用配置单元0.9.0版本。

问题是配置单元不允许您指定输出分隔符-

解决方案是使用分隔符规范为输出创建外部表,并插入覆盖表而不是目录

-

假设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 .

返回如上,带有空格。

我有一些不同的声音

实际上,配置单元不支持自定义分隔符

但当您使用INSERT OVERRIDE目录时,行中有分隔符。分隔符是“\1”

您可以使用hadoop dfs-cat$file | head-1 | xxd查找该文件,或者将该文件从HDFS获取到本地计算机,并使用vim打开它。在作为分隔符的vim中会有一些类似“^A”的字符

回到问题上来,你可以用一个简单的方法来解决它

仍然使用插入覆盖目录“/user/hadoop/output”生成/user/hadoop/output

创建字段以“\1”分隔的外部表:


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

插入覆盖目录“/user/hadoop/output”选择 图的边上的concat_ws',,col1,col2

这里我选择逗号作为列分隔符,默认分隔符是^A。在python语言中,它是\x01

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

选择col1,delimiter,col2,delimiter,col3。。。, 从桌子上


然后,将分隔符+^A视为一个新的分隔符。

我怀疑hive实际上是在写一个contol-A作为delimeter,但当你在屏幕上做一个cat时,它不会出现在你的眼前

相反,如果您只想看到一小部分,请尝试在vi中打开该文件或将其置于文件头部,然后vi显示结果:

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

vi my_local_file.txt


您应该能够在其中看到^A字符。

我遇到了一个问题,配置单元查询结果的输出应该以管道分隔。。 运行此sed命令时,可以将“^A”替换为|


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

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

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

这应该对你有用。

我认为这是一个更好的解决方案,尽管这是一种迂回的实现方式


插入覆盖目录“/user/hadoop/output”SELECT src_node_id”,dest_node_id FROM graph_edges

虽然这个问题已经有2年多的历史了,而且当时最重要的答案是正确的,但现在可以告诉配置单元将分隔数据写入目录

以下是使用传统的^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

您可以使用此参数行格式分隔字段,以“|”结尾,例如,在您的案例中应为


插入覆盖目录“/user/hadoop/output”行格式分隔字段,以“|”结尾,从图形_边选择*

我创建了一个新的非外部表,然后将外部表到内部表的数据插入HDFS文件。但仍然是相同的结果,根本没有分隔符。即使配置单元不允许指定输出分隔符,它也必须用一些分隔符来分隔输出。好的,假设HDFS中有/user/hadoop/input/graph_edges.csv,是的,graph_edges文件在HDFS中。我将编辑我的问题,把这个细节。另外,请注意,graph_Edge不是一个逗号分隔的文件,它是一个空格分隔的文件。这正是有效的。非常感谢你。所以我学到的一点是,在配置单元中,为了保留格式/分隔符,一个外部表应该总是写入另一个外部表,尽管我认为这是一个bug。是的,有一个请求能够指定插入覆盖的格式。不客气!您确定输出目录中没有分隔符吗?默认情况下,配置单元使用“\1”作为字段分隔符,因此,您应该尝试使用“hadoop dfs-cat/user/hadoop/output/*|tr'\001”“”,请确保看到@garren的答案-当前版本的配置单元允许插入覆盖目录…行格式和插入覆盖目录…存储为:配置单元版本0.11.0到1.1.0中的本地写入仅支持自定义分隔符?