【问题标题】:Remove the Junk charcters from hive tables or from unix从 hive 表或 unix 中删除垃圾字符
【发布时间】:2023-12-13 01:18:01
【问题描述】:

我们在 hive 中有如下表,我们正在从 hive 数据生成平面文件,而我们正在生成我们发现在下面的数据中有垃圾字符我们在许多列中有很多字符任何人都可以帮助我们从 hive 表或 unix 文件中删除那些垃圾字符?

ÿ,ä,í,ã

这里的问题是相同的数据在加载到那里的数据库时需要发送到下游,它显示为双美元,但我们将代码双美元设计为列分隔符。

【问题讨论】:

  • 什么是合法字符?
  • 你的帖子最后一句不清楚。
  • 我们总共有 142 个表,但我不在哪个表中哪一列有垃圾字符。基本上我从 hive 获取数据并通过 MQHUB 服务器向下游提供带有分隔符的双美元。当下游试图加载他们观察到的垃圾字符自动转换为双美元的数据时,我们的分隔符也是双美元。例如,在表中,我有 11 列带有分隔符双美元,但如果该记录有垃圾字符,那么它显示 12 个分隔符。因此他们无法插入该特定记录。
  • 知道了。我给的答案应该没问题。
  • 有什么方法可以在不创建表的情况下删除,因为我从配置单元表中获取数据我无权在生产角度创建表?

标签: sql regex hadoop hive hiveql


【解决方案1】:

基本概念

hive> select regexp_replace('Hÿelloä íworlãd','[^a-zA-Z ]','');
OK
Hello world

演示

从整个表中删除不需要的字符并将其导出到文件中。

create table t (i int,s1 string,s2 string);
insert into t values (1,'Hÿelloä','íworlãd'),(2,'ãGããood','Byÿe');

select * from t;

+---+---------+---------+
| i | s1      | s2      |
+---+---------+---------+
| 1 | Hÿelloä | íworlãd |
| 2 | ãGããood | Byÿe    |
+---+---------+---------+

create external table t_ext (rec string) 
row format delimited 
fields terminated by '0' 
location '/user/hive/warehouse/t'
;

insert overwrite local directory '/tmp/t_ext'
select  regexp_replace(regexp_replace(rec,'[^a-zA-Z0-9 \\01]',''),'\\x01','<--->') 
from    t_ext
;

! ls /tmp/t_ext
;
000000_0
! cat /tmp/t_ext/000000_0
;
1<--->Hello<--->world
2<--->Good<--->Bye

【讨论】:

    【解决方案2】:

    只要您的表仅包含“原始”类型(不包含结构、数组、映射等),此方法就可以工作。
    我真的把信封推到这里了。

    演示

    create table t (i int, dt date, str string, ts timestamp, bl boolean);
    
    insert into t select 1,current_date,'Hello world',current_timestamp,true;
    
    select * from t;
    
    +-----+------------+-------------+-------------------------+------+
    | t.i |    t.dt    |    t.str    |          t.ts           | t.bl |
    +-----+------------+-------------+-------------------------+------+
    |   1 | 2017-03-14 | Hello world | 2017-03-14 14:37:28.889 | true |
    +-----+------------+-------------+-------------------------+------+
    

    select  regexp_replace
            (   
                printf(concat('%s',repeat('$$%s',field(unhex(1),*,unhex(1))-2)),*)
               ,'(\\$\\$)|[^a-zA-Z0-9 -]'
               ,'$1'
            )
            
    from    t
    ;
    

    1$$2017-03-14$$Hello world$$2017-03-14 143728.889$$true

    【讨论】:

    • 检查更新的答案。我已经简化了解决方案,假设 $$ 没有出现在您的数据中的任何位置