HIVE针对反斜杠的正则替换问题
2013-02-28 15:31
183 查看
最近收到一份需求:
有两张表 one 和 two . 两张表都有一个字段name,现在要求从one 导入到two 中。
要求是
name字段有可能为空 ,在HIVE中默认是用"\N"来表示空,也就是ONE表在HDFS上文件包含"\N"。
同时表ONE的NAME字段中有可能包含"\r"的转行符。
ONE表类似的HDFS文件系统如下
ID NAME
1, \N
2, licl\r
现在要求导入到表TWO后,\N表示为字符串NULL,并且将\r替换成\n
导入后TWO表的HDFS文件系统应该如下
ID NAME
1, NULL
2, licl\n
原始语句:insert overwrite table TWO select id,name from ONE;
我们的思路很简单,首先处理NULL的情况,你可以使用serialization.null.format
属性来修改TWO的表结构属性。但是当时我受到环境制约不允许这样做。接下来用coalesce函数处理NAME,coalesce(A,B,C)代表返回第一个不是NULL的值
于是函数变为了insert overwrite table TWO select id,coalesce(name,'NULL') from ONE;
接下来是难点,由于HIVE是采用JAVA编写的 "\"在JAVA中有着特殊的意义,同时还涉及到了正则表达式,更加复杂了。
最初我的语句是这样的。
insert overwrite table TWO select id,regexp_replace(coalesce(name,'NULL'),‘\r’,'\n') from ONE;
发现根本不起作用。
通过查询源码,发现我的 '\r' 在经过regexp_replace函数的时候变成了对象 TEXT("\\r"),这是由于JAVA引起的。
我的正则(‘\r’)也不起作用,因为正则遇到\的时候需要使用两个\\代表一个\,同时由于这个操作是在JAVA中进行的。反斜杠的数量应该再乘以2.
所以语句改成了:
insert overwrite table TWO select id,regexp_replace(coalesce(name,'NULL'),‘\\\\r’,'\\n') from ONE;
发现TWO变成了
ID NAME
1, NULL
2, licln
n的前面少了一个反斜杠,于是语句变成了:
insert overwrite table TWO select id,regexp_replace(coalesce(name,'NULL'),‘\\\\r’,'\\\\n') from ONE;
这个程序在客户端运行的十分好。
TWO表变成了
ID NAME
1, NULL
2, licl\n
但是!当我采用JDBC的模式的时候,发现第二条记录完全没有变化,也就是说正则匹配又失败了。
我推测是jdbc传输语句的问题,反斜杠的数量再次发生了变化,于是索性。
insert overwrite table TWO select id,regexp_replace(coalesce(name,'NULL'),‘\\\\\\\\r’,'\\\\\\\\n') from ONE;
这次JDBC发送的语句也执行的很好。
至此,我们的语句写完了。
有两张表 one 和 two . 两张表都有一个字段name,现在要求从one 导入到two 中。
要求是
name字段有可能为空 ,在HIVE中默认是用"\N"来表示空,也就是ONE表在HDFS上文件包含"\N"。
同时表ONE的NAME字段中有可能包含"\r"的转行符。
ONE表类似的HDFS文件系统如下
ID NAME
1, \N
2, licl\r
现在要求导入到表TWO后,\N表示为字符串NULL,并且将\r替换成\n
导入后TWO表的HDFS文件系统应该如下
ID NAME
1, NULL
2, licl\n
原始语句:insert overwrite table TWO select id,name from ONE;
我们的思路很简单,首先处理NULL的情况,你可以使用serialization.null.format
属性来修改TWO的表结构属性。但是当时我受到环境制约不允许这样做。接下来用coalesce函数处理NAME,coalesce(A,B,C)代表返回第一个不是NULL的值
于是函数变为了insert overwrite table TWO select id,coalesce(name,'NULL') from ONE;
接下来是难点,由于HIVE是采用JAVA编写的 "\"在JAVA中有着特殊的意义,同时还涉及到了正则表达式,更加复杂了。
最初我的语句是这样的。
insert overwrite table TWO select id,regexp_replace(coalesce(name,'NULL'),‘\r’,'\n') from ONE;
发现根本不起作用。
通过查询源码,发现我的 '\r' 在经过regexp_replace函数的时候变成了对象 TEXT("\\r"),这是由于JAVA引起的。
我的正则(‘\r’)也不起作用,因为正则遇到\的时候需要使用两个\\代表一个\,同时由于这个操作是在JAVA中进行的。反斜杠的数量应该再乘以2.
所以语句改成了:
insert overwrite table TWO select id,regexp_replace(coalesce(name,'NULL'),‘\\\\r’,'\\n') from ONE;
发现TWO变成了
ID NAME
1, NULL
2, licln
n的前面少了一个反斜杠,于是语句变成了:
insert overwrite table TWO select id,regexp_replace(coalesce(name,'NULL'),‘\\\\r’,'\\\\n') from ONE;
这个程序在客户端运行的十分好。
TWO表变成了
ID NAME
1, NULL
2, licl\n
但是!当我采用JDBC的模式的时候,发现第二条记录完全没有变化,也就是说正则匹配又失败了。
我推测是jdbc传输语句的问题,反斜杠的数量再次发生了变化,于是索性。
insert overwrite table TWO select id,regexp_replace(coalesce(name,'NULL'),‘\\\\\\\\r’,'\\\\\\\\n') from ONE;
这次JDBC发送的语句也执行的很好。
至此,我们的语句写完了。
相关文章推荐
- java用正则表达式匹配或替换反斜杠(\)的问题
- java替换文本中所有的正则符号 Java问题通用解决代码
- JS正则替换问题 http://bbs.51js.com/redirect.php?fid=1&tid=67418&goto=nextnewset
- 使用VS正则表达式查找替换,批量修改Reflactor生成的代码问题
- 作业电影评分系统 HIVE实战 正则表达式(限于string)解决了HIVE 源文件多个分隔符的问题
- java中用正则表达式将/替换成//的问题
- php 用正则替换中文字符一系列问题解决
- Emacs正则表达式替换时替换字符串中含有回车符无法替换的问题
- 关于正则表达式在access读取字符后替换的问题
- 巧用多个正则表达式解决取反替换问题(解决不匹配则替换问题)——用sed和perl的正则表达式
- hive中 regexp_replace的用法,替换特殊字符问题
- java正则表达式中replace和replaceall替换换行符的小问题
- asp.net中一个正则表达式替换的问题
- 正则的反斜杠问题
- 关于Python中正则表达式的反斜杠问题
- 缓存需要注意的问题以及使用.net正则替换字符串的方法
- 用boost的正则替换解决问题
- AS3中正则表达式对反斜杠的替换
- sql server 2008 使用正则替换的问题
- 一个有趣的C#正则替换问题