perl中的文件解析读取第一行和最后一行

perl中的文件解析读取第一行和最后一行,perl,Perl,我有一个第一行的文件 ==详细日志记录已开始:2017年1月3日17:41:55生成类型:SHIP UNICODE 5.00.7601.00调用进程:C:\Windows\SysWOW64\msiexec.exe=== 最后一行呢 ==详细日志记录已停止:2017年1月3日17:49:17=== 我对这些行中的时间字段感兴趣(17:41:55和17:49:17),希望找到从开始到停止的时间差 我尝试读取数组中的文件,并获取第一行和最后一行 my $last = pop (@array); m

我有一个第一行的文件

==详细日志记录已开始:2017年1月3日17:41:55生成类型:SHIP UNICODE 5.00.7601.00调用进程:C:\Windows\SysWOW64\msiexec.exe===
最后一行呢

==详细日志记录已停止:2017年1月3日17:49:17===
我对这些行中的时间字段感兴趣(
17:41:55
17:49:17
),希望找到从开始到停止的时间差

我尝试读取数组中的文件,并获取第一行和最后一行

my $last = pop (@array);
my $first = shift (@array);
但是,获取阵列中的时间场变得越来越困难


您能建议其他方法吗?

如果您想读取一个可能非常大的日志文件的第一行和最后一行,您不应该将其全部写入一个数组,因为它可能会消耗大量内存。相反,只需阅读第一行和最后一行

你可以很容易地读第一行

 use v5.10;
 use strict;
 use warnings;
 use autodie;

 open my $fh, $logfile;
 my $first = <$fh>;
请注意,如果文件末尾有任何零散的换行符,则这些换行符将是最后一行,因此您可能希望继续阅读,直到获得所需内容为止

# 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 }
strtime
是许多语言用来解析日期(字符串解析时间)的函数<代码>strftime(字符串格式时间)用于格式化日期。他们使用相同的迷你语言。看一下文档,了解那里发生了什么

一旦你有了它


对于Schwern,我有一种稍微不那么复杂的方法,即使用Unix命令:

#!/usr/bin/perl

use strict;
use English;

my $first=`head -1 $ARGV[0]`;
my $last=`tail -1 $ARGV[0]`;

print "$first\n";
print "$last\n";

我相信
tail-1
将从文件末尾读取,因此它避免读取整个文件。不要使用原型;它们不是函数签名,而是用于非常特殊的目的。如果需要函数签名,请在较新的PERL中使用类似或
的功能“签名”
。最后,无需编写
command()
,它将为您完成这项工作
my$first=`head-1$ARGV[0]`
@Schwern谢谢,我想我在这方面已经坚持了15年了。我更新了我的答案,非常感谢。你为什么要使用英语?您实际上没有使用任何变量名。@simbabque习惯,我同意这是没有必要的。
# === 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");
}
my $start = log_time($first);
my $end   = log_time($last);

say "Seconds elapsed: ".$end - $start;
#!/usr/bin/perl

use strict;
use English;

my $first=`head -1 $ARGV[0]`;
my $last=`tail -1 $ARGV[0]`;

print "$first\n";
print "$last\n";