2

我有一个文件:

id,name,address
001,adam,1-A102,mont vert
002,michael,57-D,costa rica

我必须创建一个包含三列的配置单元表 : idnameaddress使用逗号分隔,但这里地址列本身包含逗号。我们将如何处理这个问题。

4

1 回答 1

3

一种可能的解决方案是使用 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 以提取列,如下所示:

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 添加一列。

于 2019-08-16T15:20:10.430 回答