Apache pig 使用Pig读取以空格分隔的文件

Apache pig 使用Pig读取以空格分隔的文件,apache-pig,Apache Pig,我正在尝试读取一个日志文件,其内容如下所示: 2013-03-28812:19:03.639648-05:00主机1 rpcbind:rpcbind终止于 信号。使用“rpcbind-w”重新启动 2013-03-28812:20:33.158823-05:00主机2 rpcbind:rpcbind终止于 信号。使用“rpcbind-w”重新启动 我尝试过使用存储空间分隔符,如下所示: cmessages=使用PigStorage(“”)作为(日期:chararray, 主机:chararray

我正在尝试读取一个日志文件,其内容如下所示:

2013-03-28812:19:03.639648-05:00主机1 rpcbind:rpcbind终止于 信号。使用“rpcbind-w”重新启动
2013-03-28812:20:33.158823-05:00主机2 rpcbind:rpcbind终止于 信号。使用“rpcbind-w”重新启动

我尝试过使用存储空间分隔符,如下所示:

cmessages=使用PigStorage(“”)作为(日期:chararray, 主机:chararray,消息:chararray)

但这就扼杀了第三个字段中的信息,我认为以后可能会有用

转储cmessage

<snip>
(2013-03-28T12:19:03.639648-05:00,host1,rpcbind:)
(2013-03-28T12:20:33.158823-05:00,host2,rpcbind:)
</snip>

(2013-03-28812:19:03.639648-05:00,主持人1,rpcbind:)
(2013-03-28812:20:33.158823-05:00,主持人2,rpcbind:)
有没有更好的方法来读取此日志文件,而不需要昂贵的正则表达式或UDF加载程序?猪身上应该有什么东西,在第二个空格后可能会说停止?也许不是

更新: 只是为了修改我想要的: 而不是

(2013-03-28812:19:03.639648-05:00,主持人1,rpcbind:)

我想:

(2013-03-28812:19:03.639648-05:00,主机1,rpcbind:rpcbind在信号上终止。用“rpcbind-w”重新启动)


本质上,我希望在元组的最后一个字段中显示完整的日志消息。我希望这更清楚。

如果不确切了解控制日志的规则,就没有完美的解决方案,但如果假设日期和主机具有固定长度,则可以使用以下方法:

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;
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;
如果已知它们仅由前2个空格分隔,则可以使用以下选项:

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;
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个字符。

如果不确切了解控制日志的规则,就没有完美的解决方案,但如果您假设日期和主机具有固定长度,则可以使用以下方法:

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;
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;
如果已知它们仅由前2个空格分隔,则可以使用以下选项:

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;
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个字符。

这应该是评论部分的评论。我知道,但我不能,因为我没有足够的声誉这样做。在错误的地方询问细节——IMHO——总比不回答任何事情好,因为我知道我可能会帮助这个人。啊,而不是(2013-03-28812:19:03.639648-05:00,host1,rpcbind:)我希望整个消息都包含在元组的最后一个字段中:(2013-03-28812:19:03.639648-05:00,主机1,rpcbind:rpcbind终止于信号。使用“rpcbind-w”重新启动)使用正则表达式而不是索引是否有一种好方法?例如,我的空格数未知(通常为4个)分隔我的列。我的某些列还包含空格。如果列只包含空格和连字符,我希望它为空/空白,但如果它包含数字(浮点数,通常为1到4位)我希望是这样。这应该是评论部分的评论。我知道,但我不能,因为我没有足够的声誉这么做。在错误的地方询问细节——IMHO——比什么都不回答要好,因为我知道我可能会帮助这个人。啊,而不是(2013-03-28812:19:03.639648-05:00,host1,rpcbind:)我希望整个消息都包含在元组的最后一个字段中:(2013-03-28812:19:03.639648-05:00,主机1,rpcbind:rpcbind终止于信号。使用“rpcbind-w”重新启动)是否有一种使用正则表达式而不是索引的好方法?例如,我有未知数量的空格(通常为4)分隔我的列。我的某些列还包含空格。如果列只包含空格和连字符,我希望它为空/空,但如果它包含一个数字(一个浮点数,通常为1到4位),我希望它是空的。