我有个文件:
id,name,address 001,adam,1-A102,mont vert 002,michael,57-D,costa rica
我必须创建一个包含三列的配置单元表: id , name 以及 address 使用逗号分隔,但此处地址列本身包含逗号。我们该怎么处理这件事。
id
name
address
jutyujz01#
一种可能的解决方案是使用regexserde:
CREATE TABLE table my_table ( id string, name string, address string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' WITH SERDEPROPERTIES ('input.regex'='^(.*?),(.*?),(.*?)$') location 'put location here' ;
用表位置替换location属性,并将文件放入该位置。第一组 (.*?) 将匹配第一个逗号之前的所有内容,第二组将匹配第一个逗号之后和第二个逗号之前的所有内容,第三组将匹配第二个逗号之后的所有内容。同时添加 TBLPROPERTIES("skip.header.line.count"="1") 如果需要跳过头文件,并且它始终存在于文件中。如果标头可以不存在,则可以使用筛选标头行 where id !='id' 此外,即使不创建表,也可以轻松测试regex以提取列,如下所示:
(.*?)
TBLPROPERTIES("skip.header.line.count"="1")
where id !='id'
select regexp_replace('002,michael,57-D,costa rica','^(.*?),(.*?),(.*?)$','$1|$2|$3');
结果:
002|michael|57-D,costa rica
在本例中,查询返回三个组,用|分隔。通过这种方式,您可以轻松地测试正则表达式,在使用它创建表之前检查组的定义是否正确。回答评论中的问题。您可以有带逗号的地址和一个以上不带逗号的列,如下所示:
select regexp_replace('001,adam,1-A102, mont vert,sydney','^(.*?),(.*?),(.*?),([^,]*?)$','$1|$2|$3|$4');
退货:
001|adam|1-A102, mont vert|sydney
在地址列中检查逗号是可选的:
hive> select regexp_replace('001,adam,1-A102 mont vert,sydney','^(.*?),(.*?),(.*?),([^,]*?)$','$1|$2|$3|$4');
001|adam|1-A102 mont vert|sydney
阅读本文以更好地理解:https://community.cloudera.com/t5/community-articles/using-regular-expressions-to-extract-fields-for-hive-tables/ta-p/247562 [^,] 表示不是逗号,最后一列可以是除逗号以外的所有内容。当然,在ddl中再添加一列。
[^,]
1条答案
按热度按时间jutyujz01#
一种可能的解决方案是使用regexserde:
用表位置替换location属性,并将文件放入该位置。
第一组
(.*?)
将匹配第一个逗号之前的所有内容,第二组将匹配第一个逗号之后和第二个逗号之前的所有内容,第三组将匹配第二个逗号之后的所有内容。同时添加
TBLPROPERTIES("skip.header.line.count"="1")
如果需要跳过头文件,并且它始终存在于文件中。如果标头可以不存在,则可以使用筛选标头行where id !='id'
此外,即使不创建表,也可以轻松测试regex以提取列,如下所示:结果:
在本例中,查询返回三个组,用|分隔。通过这种方式,您可以轻松地测试正则表达式,在使用它创建表之前检查组的定义是否正确。
回答评论中的问题。您可以有带逗号的地址和一个以上不带逗号的列,如下所示:
退货:
在地址列中检查逗号是可选的:
退货:
阅读本文以更好地理解:https://community.cloudera.com/t5/community-articles/using-regular-expressions-to-extract-fields-for-hive-tables/ta-p/247562
[^,]
表示不是逗号,最后一列可以是除逗号以外的所有内容。当然,在ddl中再添加一列。