在$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]
中获得价值
答案 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