从文件的后N行获取价值

时间:2018-08-20 13:27:15

标签: perl tie

$lines[0]循环之后,我在拦截正在读取的foreach上方的行内容时遇到问题

my $IN_DIR  = "/tmp/appo/log";              # Input Directories
my $jumprow = '<number of row to skip>';    # This is a value

foreach my $INPUT ( glob( "$IN_DIR/logrotate_*.log" ) ) {

    open( my $fh, '<', $INPUT ) or die $!;

    while ( <$fh> ) {

        next unless $. > $jumprow;

        my @lines = split /\n/;
        my $i     = 0;

        foreach my $lines ( @lines ) {

            if ( $lines[$i] =~ m/\A#\d.\d.+#\d{4}\s\d{2}\s\d{2}\s\d{2}:\d{2}:\d{2}:\d{3}#\+\d+#\w+#\/\w+\/\w+\/Authentication/ ) {

                # Shows only LOGIN/LOGOUT access type and exclude GUEST users

                if ( $lines[ $i + 2 ] =~ m/Login/ || $lines[ $i + 2 ] =~ m/Logout/ && $lines[ $i + 3 ] !~ m/Guest/ ) {

                    my ( $y, $m, $d, $time ) = $lines[$i] =~ /\A#\d.\d.+#(\d{4})\s(\d{2})\s(\d{2})\s(\d{2}:\d{2}:\d{2}:\d{3})/;

                    my ( $action ) = $lines[ $i + 2 ] =~ /\A(\w+)/;
                    my ( $user )   = $lines[ $i + 3 ] =~ /\w+:\s(.+)/;

                    print "$y/$m/$d;$time;$action;$user\n";
                }
            }
            else {
                next;    # Is this next technically necessary according to you?
            }

            $i++;
        }
    }

    close( $fh );
}

Tie::File 模块可以帮助我

my $IN_DIR  = "/tmp/appo/log";              # Input Directories
my $jumprow = '<number of row to skip>';    # This is a value

foreach my $INPUT ( glob( "$IN_DIR/logrotate_*.log" ) ) {

    tie @lines, 'Tie::File', $INPUT, mode => O_RDONLY;
            or die $!;

    my $i = $.;

    next unless $i > $jumprow;

    foreach my $lines ( @lines ) {

        if ( $lines[$i] =~ m/\A#\d.\d.+#\d{4}\s\d{2}\s\d{2}\s\d{2}:\d{2}:\d{2}:\d{3}#\+\d+#\w+#\/\w+\/\w+\/Authentication/ ) {

            # Shows only LOGIN/LOGOUT access type and exclude GUEST users

            if ( $lines[ $i + 2 ] =~ m/Login/ || $lines[ $i + 2 ] =~ m/Logout/ && $lines[ $i + 3 ] !~ m/Guest/ ) {

                my ( $y, $m, $d, $time ) = $lines[$i] =~ /\A#\d.\d.+#(\d{4})\s(\d{2})\s(\d{2})\s(\d{2}:\d{2}:\d{2}:\d{3})/;

                my ( $action ) = $lines[ $i + 2 ] =~ /\A(\w+)/;
                my ( $user )   = $lines[ $i + 3 ] =~ /\w+:\s(.+)/;

                print "$y/$m/$d;$time;$action;$user\n";
            }
        }
        else {
            next;    # Is this next technically necessary according to you?
        }

        $i++;
    }
}

您能告诉我我对Tie::File的声明是否正确吗? 如下面的指南mcve

所示,这只是我的主脚本的一部分

实际上没有tie时,我的主脚本仅与$lines[0]一起使用,它不会从$lines[$i+2]$lines[$i+3]中获得价值

1 个答案:

答案 0 :(得分:2)

您似乎在这里迷路了。我编写了一个工作程序来处理您在上一个问题中显示的数据。它至少应为您继续工作奠定稳定的基础。我认为这很简单,但是请问Perl文档中是否有不明显的内容

use strict;
use warnings 'all';
use feature 'say';
use autodie;  # Handle IO failures automatically

use constant IN_DIR => '/tmp/appo/log';

chdir IN_DIR; # Change to input directory
              # Status handled by autodie

for my $file ( glob 'logrotate_*.log' ) {

    say $file;
    say '-' x length $file;
    say "";

    open my $fh, '<', $file; # Status handled by autodie

    local $/ = "";           # Enable block mode

    while ( <$fh> ) {

        my @lines = split /\n/;

        next unless $lines[0] =~ /
            ^
            \# \d.\d .+?
            \# (\d\d\d\d) \s (\d\d) \s (\d\d)
            \s
            ( \d\d : \d\d : \d\d : \d\d\d )
        /x;
        my ( $y, $m, $d, $time ) = ($1, $2, $3, $4);
        $time =~ s/.*\K:/./;  # Change decimal point to dot for seconds

        next unless $lines[2] =~ /^(Log(?:in|out))/;
        my $action = $1;

        next unless $lines[3] =~ /^User:\s+(.*\S)/ and $1 ne 'Guest';
        my $user = $1;

        print "$y/$m/$d;$time;$action;$user\n";
    }

    say "";
}

输出

logrotate_0.0.log
-----------------

2018/05/24;11:05:04.011;Login;USER4
2018/05/24;11:04:59.410;Login;USER4
2018/05/24;11:05:07.100;Logout;USER3
2018/05/24;11:07:21.314;Login;USER2
2018/05/24;11:07:21.314;Login;USER2
2018/05/26;10:48:02.458;Logout;USER2
2018/05/28;10:00:25.000;Logout;USER0

logrotate_1.0.log
-----------------

2018/05/29;10:09:45.969;Login;USER4
2018/05/29;11:51:06.541;Login;USER1
2018/05/30;11:54:03.906;Login;USER4
2018/05/30;11:59:59.156;Logout;USER3
2018/05/30;08:32:11.348;Login;USER4
2018/05/30;11:09:54.978;Login;USER2
2018/06/01;08:11:30.008;Logout;USER2
2018/06/01;11:11:29.658;Logout;USER1
2018/06/02;12:05:00.465;Logout;USER9
2018/06/02;12:50:00.065;Login;USER9
2018/05/24;10:43:38.683;Login;USER1