如果可行且可行,我首先建议您探索一下是否可以通过使用逗号以外的其他内容作为字段分隔符的方式对输入数据进行清理。使用数据中可能自然出现的分隔模式总是很冒险。
但如果这不可能,那么有这种基于正则表达式的方法来检测引号引起的:
- 首先将您的数据以单列行的形式提取到临时表中(整行到每一行中)。
- 检测引号之间出现的逗号并将其替换为人工占位符。
- 使用逗号作为分隔符拆分结果字符串。
- 将人工占位符替换为它们最初表示的逗号。
作为一个人为的具体示例,我使用您的数据加载了以下单列临时表(步骤 #1):
hive> DESCRIBE staging;
OK
rawline string
Time taken: 0.238 seconds, Fetched: 1 row(s)
hive> SELECT * FROM staging;
OK
a,"b,c",d, e
p,q,"e,r", t
a,s,"t,g", t
Time taken: 0.277 seconds, Fetched: 3 row(s)
接下来的查询会生成最终的目标表。
DROP TABLE IF EXISTS test;
CREATE TABLE test (
Col1 STRING,
Col2 STRING,
Col3 STRING,
Col4 STRING
);
INSERT INTO TABLE test SELECT
regexp_replace(fields[0], "\\[QUOTEDCOMMA\\]", ","), -- Step #4
regexp_replace(fields[1], "\\[QUOTEDCOMMA\\]", ","), -- Step #4
regexp_replace(fields[2], "\\[QUOTEDCOMMA\\]", ","), -- Step #4
regexp_replace(fields[3], "\\[QUOTEDCOMMA\\]", ",") -- Step #4
FROM (
SELECT split( -- Step #2 and #3
regexp_replace(rawline, "\"([^,]*),([^,]*)\"", "$1[QUOTEDCOMMA]$2"),
',') AS fields
FROM staging
) t;
这将生成以下最终表格test:
hive> SELECT * FROM test;
OK
a b,c d e
p q e,r t
a s t,g t
Time taken: 0.196 seconds, Fetched: 3 row(s)
在此示例实现中,字符串[QUOTEDCOMMA] 被用作引号之间的逗号的人工占位符。选择是完全任意的,实际上,如果您走这条路,您需要确保您的占位符不会自然地出现在您的数据中。