【问题标题】:How can I treat many log files as one virtual file in Perl?如何在 Perl 中将多个日志文件视为一个虚拟文件?
【发布时间】:2010-09-18 10:41:27
【问题描述】:

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

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

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

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

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

上面的代码会覆盖所有的日志,但我不确定:

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

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

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

【问题讨论】:

    标签: perl filehandle


    【解决方案1】:

    如果您想确保某个特定的顺序,请自行排序,即使只是为了确保您自己会得到正确的结果:

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

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

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

    要将它们作为一个 über 文件读取,我喜欢使用 local @ARGV,这样我就可以使用菱形运算符,这实际上就是神奇的 ARGV 文件句柄。当它到达@ARGV 中一个文件的末尾时,它会移动到下一个文件。这通过在程序内部分配给@ARGV 来伪造指定命令行上的所有文件:

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

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

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

    【讨论】:

    • +1 表示标点符号。与金属乐队一样,SO 答案最好使用变音符号。
    • 您还可以使用$. 跟踪当前文件的当前行号。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-06-07
      • 2012-08-16
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多