如果您想读取可能非常大的日志文件的第一行和最后一行,则不应将其全部放入数组中,因为它可能会消耗大量内存。相反,只需阅读第一行和最后一行。
你可以很容易地阅读第一行。
use v5.10;
use strict;
use warnings;
use autodie;
open my $fh, $logfile;
my $first = <$fh>;
您可以使用seek 跳转到文件末尾,然后使用read 分块向后读取,直到获得整行。这可能会变得复杂。幸运的是,有 File::ReadBackwards 可以为您完成这项工作。
use Carp;
use File::ReadBackwards;
my $backwards = File::ReadBackwards->new( $logfile )
or croak "Can't open $logfile: $!";
my $last = $backwards->readline;
请注意,如果文件末尾有任何杂散的换行符,那将是最后一行,因此您可能需要继续阅读,直到找到所需的内容。
# Read lines backwards until we get something that
# contains non-whitespace.
while( my $last = $backwards->readline ) {
last if $last =~ /\S+/;
}
这是获取第一行和最后一行的更简单但更慢(对于大文件)的方法。像以前一样阅读第一行,然后阅读每一行,但只保留最后一行。
my $last;
while( my $line = <$fh> ) { $last = $line }
它仍然需要读取整个文件,但它只保留最后一个在内存中。
一旦你有了它,你就可以解析该行并将其转换为 Time::Piece 对象以便更轻松地使用它。
# === Verbose logging started: 1/3/2017 17:41:55 ... ===
# === Verbose logging stopped: 1/3/2017 17:49:17 ===
sub log_time {
my $line = shift;
# This captures the 1/3/2017 17:49:17 part
my($datetime) = $line =~
/^=== Verbose logging (?:started|stopped):\s*(\d+/\d+/\d+\s+\d+:\d+:\d+)/;
# Parse it into a Time::Piece object.
return Time::Piece->strptime($datetime, "%m/%d/%Y %H:%M:%S");
}
strptime 是许多语言用来解析日期(字符串解析时间)的函数。 strftime(字符串格式时间)用于格式化日期。他们共享相同的迷你语言。查看strftime 文档以了解那里发生了什么。
一旦你有了,you can get the difference in seconds by subtracting them。
my $start = log_time($first);
my $end = log_time($last);
say "Seconds elapsed: ".$end - $start;