Hive-数据文件分隔符为多字符问题

来源:互联网 发布:淘宝管家官方下载 编辑:程序博客网 时间:2024/06/05 14:13
在网上中文搜索出的结果,多半都是过时解决方法,还是推荐google,stackoverflow。
先上结论:如果是0.14以后的版本,直接用MultiDelimitSerde;否则,偏向于先预处理下源数据文件。

1. 如果是Hive 0.14 (2014-12月发布)以后的版本,就可以用MultiDelimitSerde优雅的解决这个问题。
    This issue has been resolved in hive 14 with the use of multidelimiter serde.
    Please find documentation here. https://cwiki.apache.org/confluence/display/Hive/MultiDelimitSerDe
  【示例 - 分隔符为多字符,比如P9数据的分隔符为 '|@|'】
  •    CREATE EXTERNAL TABlE tableex(id INT, name STRING)
  •    ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
  •    WITH SERDEPROPERTIES ("field.delim”=“|@|")
  •    STORED AS TEXTFILE LOCATION '/user/myusername';
   相关讨论:https://stackoverflow.com/questions/25484015/how-can-i-do-a-double-delimiter-in-hive

2.如果是老版本的Hive,就没有MultiDelimitSerde支持,只能选用以下几种替代方案
   1). 使用RegexSerDe, 正则表达式序列化反序列化器
        缺点:相较麻烦之处在于需要自己写正则表达式匹配 数据文本的格式;对正则表达式不熟的话,不容易写出正确的捕获组;目前,我也只测试过所有字段为string类型的解析;而且据说解析效率不高;
  • drop table test;
  • create table test
  • (
  • id string,
  • name string,
  • amt string
  • )
  • row format serde 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
  • with serdeproperties
  • ( 'input.regex' = '(.*)\\|@\\|(.*)\\|@\\|(.*)\\|@\\|' , 'output.format.string' = '%1$s%2$s%3$s ')
  • stored as textfile;
       当多分割符处理 处理非字符型时,正则表达式的匹配写法!测试一下是否可行!?
  • CREATE EXTERNAL TABlE tableex(id INT, name STRING)
  • ROW FORMAT 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
  • WITH SERDEPROPERTIES (
  •   "input.regex" = "^(\\d+)~\\*(.*)$"
  • )
  • STORED AS TEXTFILE
  • LOCATION '/user/myusername';

   2). 使用自定义 InputFormat,将多字符分隔符 |@| ,替换为 默认的 列分隔符 \001,这种方式网上文章较多,不重复累述
        注意:需要先将源文件预处理,将ctrl-a (\001)字符 替换为空,可以使用tr/sed处理。
   3). 预处理源文件
        I. 先将源文件中的所有ctrl-a (\001)字符 替换为空;
        II. 然后将分隔符 |@| 替换为 ctrl-a (\001)字符;
        III. 最后按照Hive默认方式进行解析;
   4). 使用自定义 SerDe
        这种方式以前只试过针对固定的二进制文件(proto格式)写通用的解析器,对于不固定的二维表格式数据文件,感觉就是在重复做MultiDelimitSerde的事情。
   











原创粉丝点击