2010-09-18 53 views
5

我有在日志目录中的多个访问日志,下面的命名约定如下:如何将多个日志文件视为Perl中的一个虚拟文件?

access.log.1284642120 
access.log.1284687600 
access.log.1284843260 

基本上,日志是“旋转”,由每天的Apache,这样他们就可以在顺序排序。

我试图“一个接一个地阅读它们”,以便它们可以被视为一个日志文件。

my @logs = glob('logs/access.log.*'); 

上面的代码将所有glob的日志,但我不知道:

  • 以何种顺序将日志组织,按字母顺序?
  • 如果我想检查“来自独特IP的最新访问时间”,我该怎么做?

我有一个Perl脚本,可以读一个单一的访问日志,方便地检查这个(我的算法是有它使用IP地址作为密钥和访问时间值大的乱码,只是不停推键/值对...)。 但我不想只将这个过程中的所有访问文件合并到一个临时文件中。

有什么建议吗?提前谢谢了。

回答

11

如果你想确保一个特定的顺序,排序它自己,哪怕只是为了保证自己,它会出来的权利:

my @files = sort { ... } glob(...); 

在这种情况下,这里的文件名是除了都一样具体的数字,你可能不需要那种块:

my @files = sort glob(...); 

读他们作为一个尤伯杯文件,我喜欢用local @ARGV这样我就可以使用钻石操作符,它实际上只是魔术ARGV文件句柄。当它到达@ARGV中的一个文件的末尾时,它将转到下一个文件。这假货通过程序内分配给@ARGV指定命令行上的所有文件:

{ 
local @ARGV = sort { ... } glob(...); 

while(<>) { 
     ...; 
     } 
} 

如果您需要知道您目前正在处理的文件,看在$ARGV

如果你需要更多的东西,你可能不得不采取暴力手段。

+1

+1标点。就像金属乐队一样,SO的回答对变音器来说更好。 – FMc 2010-09-18 12:09:09

+0

您还可以获得'$ .'的魔力,跟踪当前文件的当前行号。 – mob 2010-09-18 18:19:11

2

在Unix-Y的环境中,你可以将文件利用壳组合到一起:

my @files = glob("$dir/access.log.*"); 
open my $one_big_logfile, "-|", "cat @files" or die ...; 
while (<$one_big_logfile>) { 
    ... 
} 
相关问题