Perl - самый быстрый способ прочитать диапазон строк из файла в переменную - PullRequest
2 голосов
/ 10 июля 2010

С учетом начального и конечного номера строки, какой самый быстрый способ прочитать диапазон строк из файла в переменную?

Ответы [ 5 ]

8 голосов
/ 11 июля 2010

Используйте оператор диапазона .. (также известный как оператор триггера), который предлагает следующий синтаксический сахар:

Если любой из операндов скаляра .. является константным выражением, этот операнд считается истинным, если он равен (==) текущему номеру строки ввода (переменная $.).

Если вы планируете сделать это длянесколько файлов через <>, обязательно закройте неявный дескриптор файла ARGV, как описано в документации perlfunc для оператора eof .(Это сбрасывает количество строк в $..)

Приведенная ниже программа собирает в переменную $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)
2 голосов
/ 11 июля 2010

Вы можете использовать триггеры

while(<>) {
if (($. == 3) .. ($. == 7)) {
    push @result, $_;
}
1 голос
/ 10 июля 2010

Следующее загрузит все нужные строки файла в переменную массива.Прекратится чтение входного файла, как только будет достигнут номер конца строки:

use strict; 
use warnings;

my $start = 3;
my $end   = 6;
my @lines;
while (<>) {
    last if $. > $end;
    push @lines, $_ if $. >= $start;
}
0 голосов
/ 11 июля 2010

Чтение построчно не будет оптимальным.К счастью, кто-то уже сделал тяжелую работу :) use Tie :: File;он представляет файл в виде массива.http://perldoc.perl.org/Tie/File.html

0 голосов
/ 10 июля 2010
# 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, вы не сможете ее обойти.

Обновление:

Вы можете сделать это в один цикл спродолжить, если $. <$ start ", но вам нужно обязательно сбросить" $. "вручную на eof (), если вы выполняете итерацию или <>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...