首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Apache :如何使用Unicode字符(八进制大于177)作为字段标记

Apache :如何使用Unicode字符(八进制大于177)作为字段标记
EN

Stack Overflow用户
提问于 2016-11-07 08:46:38
回答 3查看 7.7K关注 0票数 3

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

代码语言:javascript
复制
Data1§Data2
Data3§Data4

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

但是,我们不能将§字符(即unicode U+00A7“区段符号”(参见这里) )指定为字段分隔符。

我们尝试了以下方法,但没有取得可接受的结果。

1)使用法向字段终止。

代码语言:javascript
复制
ROW FORMAT DELIMITED FIELDS TERMINATED BY '§'

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

代码语言:javascript
复制
+--------------------+--------------------+--+
| test.column1       | test.column2          |
+--------------------+--------------------+--+
| Data1?             | Data2?                |
| Data3?             | Data4?                |
+--------------------+--------------------+-

或用于八进制表示

代码语言:javascript
复制
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\247'

代码语言:javascript
复制
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\304\247'

返回:

代码语言:javascript
复制
+--------------------+--------------------+--+
| test.column1       | test.column2          |
+--------------------+--------------------+--+
| Data1?Data2        | NULL                  |
| Data3?Data4        | NULL                  |
+--------------------+--------------------+--+

2)使用RegexSerDe

代码语言:javascript
复制
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "^([^\\]]+)\\\247([^\\]]+)$")

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

代码语言:javascript
复制
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "^([^\\]]+)\\$([^\\]]+)$")

(在描述格式的表语句中,这将产生:

代码语言:javascript
复制
input.regex  ^([^\\]]+)\\\uFFFD\uFFFD([^\\]]+)$

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

选择的结果总是相同的:

代码语言:javascript
复制
+--------------------+--------------------+--+
| test.column1       | test.column2          |
+--------------------+--------------------+--+
| NULL               | NULL                  |
| NULL               | NULL                  |
+--------------------+--------------------+--+

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

1) Hive不能使用非打印的ASCII字符,这些字符的八进制数高于177。在github上的其他代码这里中,指向这一点的指针让我感到惊讶,因为github是这样写的:

胞可以在窗体'\ ooo‘中指定分隔符字符,其中ooo是介于000到177之间的三位八进制数字。

2)此外,我还发现证据表明,在这里的文档中(但在正式文档中),只有一个字节的字符可以用作字段标记,其中写道:

分隔符必须是单字节字符。

就我的研究而言,§(unicode U+00A7)是一个2字节字符(11000010:10100111)。

,这是否意味着我不能使用这个分隔符,或者有没有其他方法来使用它?

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

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

代码语言:javascript
复制
select
split(a.textcolumn, '\\,')[0] as column1
,split(a.textcolumn, '\\,')[1] as column2
from
(select translate(textcolumn, '§', ',') as textcolumn from database.stage) a;

以下是错误:

SQL : 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:Error计算转换(stagingstring,'§',';') java.lang.IllegalArgumentException: null

更新2:

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-11 07:55:53

答案在我对上述问题的更新中。但是,如果数据不干净,或者包含我找到的其他有问题的字符,这将引发错误。

票数 0
EN

Stack Overflow用户

发布于 2017-07-21 20:38:37

您需要用

Fields Terminated by '-89'

“分段符号”的十进制代码是167。

代码语言:javascript
复制
167 - 256 = -89

这个-89应该是你的分隔符。蜂巢允许分隔符在-127到127之间。

有关进一步阅读以下片段从Cloudera。

table.html

注意: CREATE子句字段终止于,转义为,行结束时具有用于其参数的字符串文字的特殊规则,因为它们都需要一个字符。您可以使用由单引号或双引号包围的常规字符、八进制序列(如'\054‘(表示逗号))或范围'-127'..'128’(带有引号但没有反斜杠)的整数,它被解释为单字节ASCII字符。从256中减去负值;例如,以'-2‘结尾的字段将字段分隔符设置为ASCII代码254,这是一些数据格式用作分隔符的“冰岛Thorn”字符。

票数 2
EN

Stack Overflow用户

发布于 2017-12-11 09:17:49

我知道这有点冷,但是这个问题可以用MultiDelimitSerDe来解决。

实际上,Hive默认SerDe (称为LazySimpleSerDe)只支持单字节分隔符。正如声码器所说,这还没有记录在案。您需要阅读源代码才能理解它。

MultiDelimitSerDe被设计为支持多字符分隔符.幸运的是,它支持任何多字节字符.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40461000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档