hadoop - Apache hive : How to use Unicode character (with octal above 177) as field delim

标签 hadoop unicode utf-8 hive

在我们的用例中,我们将获取格式如下的 UTF-8 文本数据:

Data1§Data2
Data3§Data4

现在我们希望在 Apache Hive 中将 Data1 和 Data3 放在一列中,将 Data2 和 Data4 放在一列中。听起来很简单。

但是,我们无法将 § 字符(即 unicode U+00A7“Section Sign”参见 here)指定为字段分隔符。

我们已经尝试了以下方法,都没有达到可接受的结果。

1) 使用方法终止的普通字段

ROW FORMAT DELIMITED FIELDS TERMINATED BY '§'

返回(注意附加到每个单元格的 ?,在其他客户端中,unicode 符号表示无法识别的符号)

+--------------------+--------------------+--+
| test.column1       | test.column2          |
+--------------------+--------------------+--+
| Data1?             | Data2?                |
| Data3?             | Data4?                |
+--------------------+--------------------+-

或八进制表示

ROW FORMAT DELIMITED FIELDS TERMINATED BY '\247'

ROW FORMAT DELIMITED FIELDS TERMINATED BY '\304\247'

返回:

+--------------------+--------------------+--+
| test.column1       | test.column2          |
+--------------------+--------------------+--+
| Data1?Data2        | NULL                  |
| Data3?Data4        | NULL                  |
+--------------------+--------------------+--+

2) 使用RegexSerDe

ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "^([^\\]]+)\\\247([^\\]]+)$")

(在某些测试源数据中将字段分隔符更改为/并使用\057(八进制代表/)会产生正确的结果,但更改源数据对我们来说不可行。)

ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "^([^\\]]+)\\$([^\\]]+)$")

(在 describe 格式化表语句中,这会产生:

input.regex  ^([^\\]]+)\\\uFFFD\uFFFD([^\\]]+)$

其中\uFFFD 是未识别符号的 unicode 表示)

SELECT 的结果总是相同的:

+--------------------+--------------------+--+
| test.column1       | test.column2          |
+--------------------+--------------------+--+
| NULL               | NULL                  |
| NULL               | NULL                  |
+--------------------+--------------------+--+

到目前为止,我的研究表明:

1) Hive 无法使用八进制数高于 177 的不可打印的 ASCII 字符。指向此的指针在其他一些代码中令我感到惊讶 here在 github 上说:

Hive can specify delimiter characters in the form '\ooo' where ooo is a three-digit octal number between 000 and 177.

2) 我还发现只有一字节字符可以用作字段分隔符的证据 here在 BigSQL 的文档中(但不在官方文档中)它说:

Delimiters must be single-byte characters

根据我的研究,§ (unicode U+00A7) 是一个 2 字节的字符 (11000010:10100111)

这是否意味着我不能使用这个定界符,或者有其他方法可以使用它吗?

小更新,如果这个问题仍未解决并且有人需要它:

我尝试了以下方法,将数据暂存为单列表,然后将 § 转换为 ,(逗号),然后用逗号将其拆分。这适用于小样本数据,但对于我的包含 200 多列错误的较大生产表则失败。

select
split(a.textcolumn, '\\,')[0] as column1
,split(a.textcolumn, '\\,')[1] as column2
from
(select translate(textcolumn, '§', ',') as textcolumn from database.stage) a;

这里是错误:

SQL 错误:java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException:评估翻译时出错(stagingstring,'§',';') java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException:评估翻译时出错(stagingstring,'§',';') java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException:评估翻译时出错(stagingstring,'§',';') org.apache.hadoop.hive.ql.metadata.HiveException:评估翻译时出错(stagingstring,'§',';') org.apache.hadoop.hive.ql.metadata.HiveException:评估翻译时出错(stagingstring,'§',';') java.lang.IllegalArgumentException: null

更新 2:

上述方法可行,但如果源数据不干净(有其他 UTF-8 问题),则会抛出上述错误。

最佳答案

您需要使用

创建表格

由“-89”终止的字段

'section sign' 的十进制代码是 167。

167 - 256 = -89

这个 -89 应该是你的分隔符。 Hive 允许使用 -127 到 127 范围内的分隔符。

如需进一步阅读以下来自 Cloudera 的代码片段。

https://www.cloudera.com/documentation/enterprise/5-8-x/topics/impala_create_table.html

注意:CREATE TABLE 子句 FIELDS TERMINATED BY、ESCAPED BY 和 LINES TERMINATED BY 对用于其参数的字符串文字有特殊规则,因为它们都需要一个字符。您可以使用由单引号或双引号括起来的常规字符、八进制序列,例如 '\054'(表示逗号),或范围在 '-127'..'128' 内的整数(带引号但不带引号)反斜杠),它被解释为单字节 ASCII 字符。 256减去负值;例如,FIELDS TERMINATED BY '-2' 将字段分隔符设置为 ASCII 代码 254,“Icelandic Thorn”字符用作某些数据格式的分隔符。

关于hadoop - Apache hive : How to use Unicode character (with octal above 177) as field delim,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40461000/

相关文章:

windows - 我无法从我的本地计算机 ping windows azure VM 的 VIP

css - 如何仅将字体应用于一定范围的 Unicode 字符

unicode - Google Fonts 中无法访问的字形和符号

c# - IndexOf 和序号字符串比较

ios - 解码混淆值 - 无法将数据转换为字符串

hadoop - Storm hdfs如何写入不同的文件路径

java - 在Java中将不同类型的数据序列化为ORC格式

hadoop - 测试与 HDFS 的连接

php - UTF-8贯穿始终

mysql - 在具有不同字符集的两个 MySQL 之间迁移数据,搞砸了 utf8