我有一个日志文件,我需要使用REGEX存储数据。我试过下面的查询,但加载所有NULL值。我已经使用http://www.regexr.com/检查了REGEX,它对我的数据工作正常。
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
感谢。
答案 0 :(得分:1)
使用您当前的表定义,没有正则表达式可以执行您正在寻找的内容。原因是您的file_format设置为 TEXTFILE ,它会在数据之前逐行(\r
,\n
或\r\n
)拆分输入文件永远到了SerDe。
然后将每一行单独传递给 RegexSerDe ,与正则表达式匹配,任何非匹配返回 NULL 。因此,多行正则表达式无法使用STORED AS TEXTFILE
。这也是您收到所有 NULL 行的原因:因为输入的任何一行都不匹配您的整个正则表达式。
这里的一个解决方案可能是预处理数据,这样每条记录只在输入文件的一行上,但这不是你要求的。
在Hive中执行此操作的方法是使用不同的file_format:
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
TextInputFormat从当前配置中读取名为 textinputformat.record.delimiter 的配置变量。如果您使用的是 TextInputFormat ,则此变量会告诉Hadoop和Hive一条记录的结束位置以及下一条记录的开始位置。
因此,将此值设置为EOR
类似意味着输入文件将在EOR
上拆分,而不是按行划分。然后,由拆分生成的每个块将作为整个块传递给RegexSerDe,newlines&所有
您可以在多个位置设置此变量,但如果这只是此(以及会话中的后续)查询的分隔符,则可以执行以下操作:
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条记录,以及您尝试为数据包捕获的内容),我或许可以帮助更多。就目前而言,您的正则表达式与您提供的示例数据不匹配 - 甚至不在the site you linked上。