如何将许多日志文件视为Perl中的一个虚拟文件?

时间:2010-09-18 10:41:27

标签: perl filehandle

我在日志目录中有多个访问日志,遵循以下命名约定:

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

基本上,Apache每天“轮换”日志,因此可以按顺序对它们进行排序。

我正在尝试“一个接一个地阅读它们”,以便将它们视为一个日志文件。

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

以上代码将对所有日志进行全局处理,但我不确定:

  • 按字母顺序排列日志的顺序是什么?
  • 如果我想查看“来自唯一IP的最新访问时间”,我该怎么做?

我有一个Perl脚本可以读取单个访问日志并轻松检查(我的算法是使用一个大的哈希,它使用IP地址作为密钥,访问时间作为值,只需继续按键/值配对它...)。 但我不想只是为了这个过程将所有访问文件合并到一个临时文件中。

有什么建议吗?非常感谢提前。

2 个答案:

答案 0 :(得分:11)

如果您想确保特定订单,请自行排序,即使只是为了确保自己能够正确排序:

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

在这种情况下,除特定数字外,文件名都相同,您可能不需要排序块:

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

要将它们作为一个ber文件读取,我喜欢使用local @ARGV,因此我可以使用菱形运算符,它实际上只是魔术ARGV文件句柄。当它到达@ARGV中的一个文件的末尾时,它会移到下一个文件。这假装通过在程序中分配@ARGV来指定命令行上的所有文件:

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

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

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

如果你需要更加花哨的东西,你可能不得不求助于暴力。

答案 1 :(得分:2)

在Unix-y环境中,您可以利用shell将文件分组在一起:

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