使用 Pig 读取以空格分隔的文件
Posted
技术标签:
【中文标题】使用 Pig 读取以空格分隔的文件【英文标题】:Reading a space-delimited file with Pig 【发布时间】:2013-04-02 03:42:32 【问题描述】:我正在尝试读取内容如下所示的日志文件:
2013-03-28T12:19:03.639648-05:00 host1 rpcbind:rpcbind 终止于 信号。使用“rpcbind -w”重新启动 2013-03-28T12:20:33.158823-05:00 host2 rpcbind:rpcbind 终止于 信号。用“rpcbind -w”重启
我尝试过像这样使用 PigStorage 空间分隔符:
cmessages = LOAD 'data.txt' USING PigStorage(' ') AS (date:chararray, 主机:字符数组,消息:字符数组);
但这会扼杀第三个字段中的信息,我认为以后可能会有用。
转储消息;
<snip>
(2013-03-28T12:19:03.639648-05:00,host1,rpcbind:)
(2013-03-28T12:20:33.158823-05:00,host2,rpcbind:)
</snip>
有没有更好的方法来读取这个日志文件,而不需要昂贵的正则表达式或 UDF 加载器? Pig中应该有一些东西可能会在第二个空格之后说停止?也许不吧。
更新: 只是为了修改我想要的: 而不是
(2013-03-28T12:19:03.639648-05:00,host1,rpcbind:)
我想要:
(2013-03-28T12:19:03.639648-05:00, host1, rpcbind: rpcbind 终止信号。使用“rpcbind -w”重新启动)
基本上,我想要元组的最后一个字段中的完整日志消息。我希望这更清楚。
【问题讨论】:
【参考方案1】:如果不确切了解控制日志的规则,就没有完美的解决方案,但如果您假设日期和主机具有固定长度,则可以使用以下方法:
A = load 'mydata' as (log:charray);
B = foreach A generate SUBSTRING(name, 0, 31) AS date,
SUBSTRING(name, 33, 37) AS host,
SUBSTRING(name, 39, 255) AS message;
如果只知道它们由前 2 个空格分隔,您可以使用以下内容:
A = load 'mydata' as (log:charray);
B = foreach A generate log, INDEXOF(log, ' ', 0) as index;
C = foreach B generate log, index, INDEXOF(log, ' ', index + 1) AS index2;
D = foreach C generate SUBSTRING(log, 0, index) AS date,
SUBSTRING(log, index + 1, index2) as host,
SUBSTRING(log, index2+1, 255) as message;
您必须了解有关日志的“规则”,然后选择适当的方法。在这里,我还假设您最长的日志是 256 个字符长。
【讨论】:
这应该是评论区的评论。 我知道,但我做不到,因为我没有足够的 reputation 这样做。在错误的地方询问细节是---恕我直言---总比什么都不回答要好,因为我知道我可能会帮助这个人。 啊,而不是 (2013-03-28T12:19:03.639648-05:00,host1,rpcbind:) 我希望整个消息包含在元组的最后一个字段中:( 2013-03-28T12:19:03.639648-05:00,host1,rpcbind:rpcbind 终止信号。使用“rpcbind -w”重新启动) 有没有使用正则表达式而不是索引的好方法?例如,我有一个未知数量的空格(通常是 4 个)分隔我的列。我的一些专栏也包含空格。如果一列只包含空格和连字符,我希望它为 NULL/空白,但如果它包含一个数字(浮点数,通常为 1 到 4 位),我希望它是那个。以上是关于使用 Pig 读取以空格分隔的文件的主要内容,如果未能解决你的问题,请参考以下文章