在PIG中从日志时间戳提取日份的技术咨询
嘿,我来帮你搞定用Pig从Apache日志的时间戳里提取日份的问题!
步骤1:先确认加载后的日志结构
你已经用CombinedLogLoader加载了日志,先执行这条命令确认字段结构,方便后续操作:
DESCRIBE logs;
这个Loader的默认输出字段是:(ip:chararray, user:chararray, user2:chararray, time:chararray, method:chararray, url:chararray, proto:chararray, status:int, bytes:int, referer:chararray, agent:chararray),其中time字段就是带方括号的目标字符串(比如你示例里的[17/Oct/2014:00:04:36 -0400])。
步骤2:清洗时间字段(去掉方括号)
首先得把时间字符串里的方括号去掉,用REGEX_EXTRACT函数就能轻松搞定:
logs_clean = FOREACH logs GENERATE time, REGEX_EXTRACT(time, '\\[(.*)\\]', 1) AS clean_time;
这里的正则\\[(.*)\\]会匹配整个带方括号的内容,捕获组1会提取出中间的纯时间部分,比如得到17/Oct/2014:00:04:36 -0400。
步骤3:提取日份(两种常用方法)
从清洗后的时间字符串里提取日份,有两种简单的实现方式:
方法一:正则直接提取
用正则匹配第一个/前面的数字,一步到位:
logs_with_day = FOREACH logs_clean GENERATE time, clean_time, REGEX_EXTRACT(clean_time, '(\\d+)/.*', 1) AS day:chararray;
这个正则(\\d+)/.*会捕获/前的所有数字,也就是我们要的日份(示例里会得到17)。
方法二:分割字符串提取
把清洗后的时间按/分割,取第一个元素:
logs_split = FOREACH logs_clean GENERATE time, clean_time; logs_split_day = FOREACH logs_split GENERATE time, clean_time, SPLIT(clean_time, '/') AS time_parts; logs_with_day = FOREACH logs_split_day GENERATE time, clean_time, time_parts.$0 AS day:chararray;
分割后的time_parts.$0就是日份部分,结果和方法一一致。
完整可运行代码
把所有步骤整合起来,你可以直接执行:
-- 加载日志文件 logs = LOAD 'sample_log' USING org.apache.pig.piggybank.storage.apachelog.CombinedLogLoader(); -- 一次性完成时间清洗和日份提取 logs_with_day = FOREACH logs GENERATE ip, time, REGEX_EXTRACT(REGEX_EXTRACT(time, '\\[(.*)\\]', 1), '(\\d+)/.*', 1) AS day:chararray; -- 查看提取结果 DUMP logs_with_day;
内容的提问来源于stack exchange,提问作者arunK
相关产品推荐
相关产品推荐

