使用正则分隔符加载数据到Hive表时出现多余空值行问题
Hive加载HDFS文件出现空行的成因及解决办法
我之前也碰到过一模一样的问题!加载HDFS文件到Hive表时每一行后面跟着空值行,大概率是这几个原因导致的,给你拆解下:
1. 换行格式不兼容(Windows vs Linux)
如果你的原始文件是在Windows环境生成的,换行符是\r\n(CRLF),但Hive默认用Linux风格的\n(LF)作为行分隔符。这时候Hive会把\r当成单独的一行,而这行内容匹配不上你的正则规则,就会生成空值行。
解决办法:
- 转换文件格式:用
dos2unix工具处理文件(本地处理后上传,或在集群节点执行):dos2unix /local/path/to/your/file hdfs dfs -put /local/path/to/your/file /hdfs/target/path/ - 或者在创建Hive表时指定行分隔符为
\r\n:CREATE TABLE your_table ( log_time STRING, log_level STRING, log_content STRING ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' WITH SERDEPROPERTIES ( "input.regex" = "([0-9]+/[A-Za-z]+/[0-9]+ [0-9]+:[0-9]+:[0-9]+) (INFO) (.*)", "line.delim" = "\r\n" ) LOCATION '/hdfs/path/to/your/file';
2. 正则表达式匹配规则过于宽松
如果你的正则表达式允许匹配空内容(比如用了.*这种无限制的匹配模式),当Hive遇到文件里的空白行(比如文件末尾的空行),或者被误解析的换行符时,正则会匹配空字符串,从而生成空值行。
比如你的数据格式是时间+级别+内容,要是正则写成(.*) (.*) (.*),那空白行也会被匹配,直接生成全空的行。
解决办法:
- 优化正则,精准匹配有效行:针对你的数据,正则可以写成更严格的版本,比如:
"input.regex" = "([0-9]{2}/[A-Za-z]{3}/[0-9]{4} [0-9]{1,2}:[0-9]{2}:[0-9]{2}) (INFO) (.*)" - 或者查询时直接过滤空行:
SELECT * FROM your_table WHERE log_time IS NOT NULL;
3. 原始文件本身存在空白行
有可能你的HDFS文件里本来就包含看不见的空白行——比如生成文件时程序多输出了换行,或者手动编辑时不小心添加的。Hive加载时自然会把这些空白行解析成空值行。
解决办法:
- 先检查文件内容:
如果输出的行数比原始数据少,说明确实有空白行。hdfs dfs -cat /hdfs/path/to/your/file | grep -v "^$" - 清理文件后重新加载:
hdfs dfs -cat /hdfs/path/to/your/file | grep -v "^$" > cleaned_file hdfs dfs -put cleaned_file /hdfs/target/path/
内容的提问来源于stack exchange,提问作者Micah Pearce
相关产品推荐
相关产品推荐

