当t
在值中并且分隔符也t
时,我们如何处理Hive中的数据。例如,假设有一列作为Street
,数据类型为String
,值为XXXtYYY
,在创建表时,我们使用字段分隔符作为t
。分隔符将如何工作?在这种情况下,值中的t
也会被分隔吗?
如果带有t
值的列用引号字符括起来,例如 "
您可以使用 csv-serde 像这样解析数据:
这是我加载的示例数据集:
R1Col1 R1Col2 "R1Col3 MoreData" R1Col4
R2Col2 R2Col2 "R2Col3 MoreData" R2Col4
从配置单元控制台注册 jar
hive> add jar /path/to/csv-serde-1.1.2-0.11.0-all.jar;
创建具有指定 serde 和自定义属性的表
hive> create table test_table(c1 string, c2 string, c3 string, c4 string) > row format serde 'com.bizo.hive.serde.csv.CSVSerde' > with serdeproperties( > "separatorChar" = "t", > "quoteChar" = """, > "escapeChar" = "\" > ) > stored as textfile;
将数据集加载到表中:
hive> load data inpath '/path/to/file/in/hdfs' into table test_table;
执行
select * from test_table
以检查结果
你可以从这里下载csv-serde。
它会将其视为分隔符,是的,就像您有一个分号一样; 在值中并告诉它在分号上拆分 - 扫描文本时,它会看到字符并将其解释为字段的边缘。
为了解决这个问题,我在将字符加载到 Hive 之前使用 sed 查找和替换字符,或者我使用不同的分隔符创建了 Hive 表,或者将其保留为默认值 ^A 或 \001,然后,当我提取它时,在输出上使用 sed 将 \001 替换为逗号或制表符或任何我需要的东西。在命令行上运行 sed -i 's/oldval/newval/g' 文件将替换文件中的字符。
是否有理由选择使用 \t 作为分隔符而不是默认的 Hive 字段分隔符 ^A 制作表?由于制表符是文本中相当常见的字符,并且Hadoop/Hive经常用于处理文本,因此很难找到一个好的字符来分隔。
我们在将数据加载到 Hadoop集群时也遇到了同样的情况。我们所做的,每当我们看到分隔符包含在数据字段中时\t
添加,并在表定义中添加以下内容。
行格式分隔的字段以t
转义结尾\
以 n
结尾的行