我知道$.
显示$/
设置为"\n"
时的行号。
我想在Perl中模拟Unix tail
命令并打印文件中的最后10行,但$.
不起作用。如果文件包含14行,则在下一循环中从15开始。
#!/usr/bin/perl
use strict;
use warnings;
my $i;
open my $fh, '<', $ARGV[0] or die "unable to open file $ARGV[0] :$! \n";
do { local $.; $i = $. } while (<$fh>);
seek $fh, 0, 0;
if ($i > 10) {
$i = $i - 10;
print "$i \n";
while (<$fh>) {
#local $.;# tried doesn't work
#undef $.; #tried doesn't work
print "$. $_" if ($. > $i);
}
}
else {
print "$_" while (<$fh>);
}
close($fh);
我想重置$.
,以便在下一个循环中有用。
答案 0 :(得分:5)
将local
与$.
一起使用会超出您的想法:
本地化$。将不会 本地化文件句柄的行数。相反,它将本地化 perl的概念是哪个文件句柄$。目前是别名。
$.
不是只读的,可以正常分配。
1 while <$fh>;
my $i = $.;
seek $fh, $. = 0, 0;
答案 1 :(得分:0)
您必须重新打开文件句柄。否则,如您所见,行号继续增加
#!/usr/bin/perl
use strict;
use warnings;
my ($filename) = @ARGV;
my $num_lines;
open my $fh, '<', $filename or die qq{Unable to open file "$filename" for input: $!\n};
++$num_lines while <$fh>;
open $fh, '<', $filename or die qq{Unable to open file "$filename" for input: $!\n};
print "$num_lines lines\n";
while ( <$fh> ) {
print "$. $_" if $. > $num_lines - 10;
}
这是一种更简洁的方式
#!/usr/bin/perl
use strict;
use warnings;
my ($filename) = @ARGV;
my @lines;
open my $fh, '<', $filename or die qq{Unable to open file "$filename" for input: $!\n};
while ( <$fh> ) {
push @lines, $_;
shift @lines while @lines > 10;
}
print @lines;