使用regex在配置单元create&load查询中获取空值

wgxvkvu9  于 2021-06-02  发布在  Hadoop
关注(0)|答案(1)|浏览(324)

我有一个日志文件,需要用regex存储数据。我尝试了下面的查询,但加载了所有空值。我查过正则表达式了http://www.regexr.com/,对我的数据来说效果很好。

CREATE EXTERNAL TABLE IF NOT EXISTS avl(imei STRING,packet STRING)                        
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (                                             
"input.regex" = "(IMEI\\s\\d{15} (\\b(\\d{15})([A-Z0-9]+)) )",          
"output.format.string" = "%1$s %2$s"                              
)
STORED AS TEXTFILE;

LOAD DATA INPATH 'hdfs:/user/user1/data' OVERWRITE INTO TABLE avl;

请在这里纠正我。
日志示例:

[INFO_|01/31 07:19:29]  IMEI 356307043180842 
[INFO_|01/31 07:19:33]  PacketLength = 372
[INFO_|01/31 07:19:33]  Recv HEXString : 0000000000000168080700000143E5FC86B6002F20BC400C93C6F000FF000E0600280007020101F001040914B34238DD180028CD6B7801C7000000690000000143E5FC633E002F20B3000C93A3B00105000D06002C0007020101F001040915E64238E618002CCD6B7801C7000000640000000143E5FC43FE002F20AA800C9381700109000F06002D0007020101F001040915BF4238D318002DCD6B7801C70000006C0000000143E5FC20D6002F20A1400C935BF00111000D0600270007020101F001040916394238B6180027CD6B7801C70000006D0000000143E5FBF5DE002F2098400C9336500118000B0600260007020101F0010409174D42384D180026CD6B7801C70000006E0000000143E5FBD2B6002F208F400C931140011C000D06002B0007020101F001040915624238C018002BCD6B7801C70000006F0000000143E5FBAF8E002F2085800C92EB10011E000D06002B0007020101F0010409154C4238A318002BCD6B7801C700000067000700005873

谢谢。

oaxa6hgo

oaxa6hgo1#

在当前的表定义中,没有正则表达式可以满足您的要求。原因是您的文件格式设置为textfile,这将按行分割输入文件( \r , \n ,或 \r\n )在数据到达服务器之前。
然后将每一行分别传递给regexserde,与您的regex匹配,任何不匹配的都返回null。因此,多行正则表达式不能使用 STORED AS TEXTFILE . 这也是您收到所有空行的原因:因为并没有一行输入与您的整个regex匹配。
这里的一个解决方案可能是预处理数据,使每个记录只在输入文件中的一行,但这不是您所要求的。
在配置单元中执行此操作的方法是使用不同的文件格式:

STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'

textinputformat从当前配置中读取一个名为textinputformat.record.delimiter的配置变量。如果您使用的是textinputformat,这个变量会告诉hadoop和hive一条记录的结束位置和下一条记录的开始位置。
因此,将此值设置为 EOR 意味着输入文件在 EOR ,而不是排队。分割生成的每个块将作为一个整体块newlines&all传递给regexserde。
可以在多个位置设置此变量,但如果这是仅用于此(以及会话内的后续)查询的分隔符,则可以执行以下操作:

SET textinputformat.record.delimiter=EOR;

CREATE EXTERNAL TABLE ...
...
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
   "input.regex" = ...
   "output.regex" = ...
)
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
          OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION ...;

在你的特定场景中,我不知道你会用什么 textinputformat.record.delimiter 而不是 EOF ,因为我们只得到了一个示例记录,我无法根据正则表达式判断您要捕获第二个字段。
如果您能提供这两个项目(包含>1条记录的示例数据,以及您试图为数据包捕获的内容),我可能可以提供更多帮助。就目前的情况而言,您的正则表达式与您提供的示例数据不匹配——甚至在您链接的站点上也不匹配。

相关问题