给定起始行和结束行号,从文件到变量读取一系列行的最快方法是什么?
答案 0 :(得分:8)
使用range operator ..
(也称为触发器操作符),它提供以下语法糖:
如果标量
..
的任一操作数是常量表达式,如果该操作数与当前输入行号(==
变量)相等($.
),则该操作数被视为true。
如果您计划通过<>
对多个文件执行此操作,请务必按perlfunc documentation for the eof
operator中所述关闭隐式ARGV
文件句柄。 (这会重置$.
中的行数。)
下面的程序收集命令行中命名的所有文件的变量$lines
第3到第5行,并在最后打印它们。
#! /usr/bin/perl
use warnings;
use strict;
my $lines;
while (<>) {
$lines .= $_ if 3 .. 5;
}
continue {
close ARGV if eof;
}
print $lines;
示例运行:
$ ./prog.pl prog.pl prog.c main.hs use warnings; use strict; int main(void) { import Data.Function (on) import Data.List (sortBy) --import Data.Ord (comparing)
答案 1 :(得分:2)
您可以使用触发器操作符
while(<>) {
if (($. == 3) .. ($. == 7)) {
push @result, $_;
}
答案 2 :(得分:1)
以下内容将文件的所有所需行加载到数组变量中。一旦到达结束行号,它将立即停止读取输入文件:
use strict;
use warnings;
my $start = 3;
my $end = 6;
my @lines;
while (<>) {
last if $. > $end;
push @lines, $_ if $. >= $start;
}
答案 3 :(得分:0)
逐行阅读并不是最佳选择。幸运的是,有人已经完成了努力工作:) 使用Tie :: File;它将文件显示为数组。 http://perldoc.perl.org/Tie/File.html
答案 4 :(得分:-2)
# cat x.pl
#!/usr/bin/perl
my @lines;
my $start = 2;
my $end = 4;
my $i = 0;
for( $i=0; $i<$start; $i++ )
{
scalar(<STDIN>);
}
for( ; $i<=$end; $i++ )
{
push @lines, scalar(<STDIN>);
}
print @lines;
# cat xxx
1
2
3
4
5
# cat xxx | ./x.pl
3
4
5
#
否则,你在不需要的时候阅读了很多额外的行。实际上,print @lines可能是复制内存,因此在读取第二个for循环时迭代打印可能是一个更好的主意。但是如果你需要将它“存储”在perl中的变量中,那么你可能无法绕过它。
更新
你可以在一个循环中使用“continue if $。&lt; $ start”,但你需要确保重置“$”。如果你正在迭代或者&lt;&gt;。
,请手动执行eof()