查找文件中的文本块数

时间:2018-07-27 11:00:20

标签: perl rotation

我有以下代码

foreach my $filename (glob("$MY_DIR/applog_s*.log")) {

    open (FILE, $filename ) or die "can't read open $filename";

    $/ = "\n\n";

    while( <FILE> ) {
        my $count = $.;
        my @ino = stat($filename);
        push @filelist, { filename => $filename , inode => $ino[1], nrow => $count};
}

以及以下数据

"$filelist{filename};$filelist{inode};$filelist{nrow}"
applog_s0.0.log;139279;1
applog_s0.1.log;139279;2
applog_s0.2.log;139279;3
applog_s0.3.log;139279;4
applog_s1.0.log;139281;5
applog_s1.1.log;139281;6
applog_s1.2.log;139281;7
applog_s1.3.log;139281;8
applog_s2.0.log;139285;9
applog_s2.1.log;139285;10
applog_s2.2.log;139285;11
applog_s2.3.log;139285;12
applog_s3.0.log;139287;13
applog_s3.1.log;139287;14
applog_s3.2.log;139287;15
applog_s3.3.log;139287;16

我有两个问题:

  • 如何解决有关计数器的错误?文件更改时,它不会从1重新开始。
  • 如何为每个文件名打印nrow的最大值?

新解决方案(有效)

foreach my $filename (glob("$MY_DIR/applog_s*.log")) {
open my $fh, '<', $filename  or die "can't read open $filename";
$/ = "\n\n";
while( <$fh> ) {
    my $inode = (stat($filename))[1];
    my @lines = split /\n\n/;

    ....
    {My data capture}
    ....

    1 while <$fh>; my $count = $.;
    push @filelist, {filename => $filename, inode => $inode, count => $count,}
    }
close ($fh);
}

1 个答案:

答案 0 :(得分:4)

如果您在perlvar中阅读了$.的文档,您会看到它说:

  

$.在关闭文件句柄时被重置,但是在没有介入的close()的情况下重新打开打开的文件句柄时不会重置。

这就是您要跌倒的地方。您不断地重新打开FILE而不先关闭它-因此$.会继续增大。

您可以在循环结束时向close()添加呼叫。但是我认为,改用词法文件句柄是一个更好的主意-因此它们会在循环的每次迭代结束时自动关闭。

foreach my $filename (glob(...)) {
  open my $fh, '<', $filename or die ...;

  local $/ = "\n\n"; # Always localise changes to $/!

  while (<$fh>) {
    ...
  }
}

关于您的其他问题,我认为您需要对代码进行一些更为剧烈的重构。您似乎为每个文件中的每一行都向@filelist中添加了一个值-听起来您确实只希望每个文件中的@filelist中有一个值。

类似这样的东西:

foreach my $filename (glob(...)) {
  open my $fh, '<', $filename or die ...;

  local $/ = "\n\n"; # Always localise changes to $/!

  my @data = <$fh>; # You don't seem to use this data anywhere
  my $inode = (stat($filename))[1];
  push @filelist, {
    filename => $filename,
    inode    => $inode,
    count    => $.,
  }
}