我有一个每30秒填充一次的日志文件。我需要找到一个字符串的最后30次出现(即每15分钟后)。之后,我需要将它们保存在一个数组中。
字符串的格式为(55.89)K/s
。应该使用什么正则表达式?
另外,由于文件中存在锁定(当时正在写入),Perl是否仍可以为我执行此操作?
答案 0 :(得分:1)
我需要找到一个字符串的最后30次出现(即每次出现之后) 15分钟)。之后,我需要将它们保存在一个数组中。
use strict;
use warnings;
use 5.016;
my $fname = 'mylog.log';
open my $LOGFILE, '<', $fname
or die "Couldn't open $fname for reading: $!";
my $text;
{
local $/ = undef;
$text = <$LOGFILE>;
}
my $regex = qr{
[(]
\d\d
[.]
\d\d
[)]
K/s
}xms;
my @matches = ($text =~ /$regex/g);
my $n = 2;
my @last_n_matches = @matches[-$n..-1];
say for @last_n_matches;
--output:--
(22.22)K/s
(33.33)K/s
要每n分钟执行一次perl脚本,请参阅此处:
http://perlmaven.com/how-to-run-a-perl-script-automatciall-every
此外,由于文件中存在锁定(正在写入 那时候,Perl还可以为我做这个吗?
是。仅通过难以检查锁定的代码来观察锁定。但是,如果您不等待锁打开,那么如果您的perl代码篡改文件的同时将某个数字写入日志文件,那么最终可能会有一半的数字,这意味着正则表达式不匹配,你会错过这个数字。
答案 1 :(得分:0)
我使用grep
和tail
:
grep '\(\d+\.\d+\)K/s' | tail -30
以下是使用Perl执行此操作的方法:
use Modern::Perl;
my @log;
open my $fh, '<', "/path/to/logfile";
while(<$fh>) {
chomp;
push @log, $_ if /\(\d+\.\d+\)K\/s/;
}
say for @log[-30 .. -1];