Хранение строк файла в массиве


Так что я довольно новичок в Perl, только изучал его в течение 1 недели. Я пытаюсь читать только определенный диапазон строк в массив. Если я печатаю $_ внутри оператора if, он перечисляет именно то, что я хочу сохранить в своем массиве. Но сохранение $_ в моем массиве, а затем печать @ array за пределами while ничего не показывает. Я не знаю, что мне делать. Причина, по которой я пытаюсь сохранить его в массиве, заключается в том, чтобы получить определенную информацию из столбцов, поэтому для этого нужен массив. Спасибо за вашу помощь. Его наверное, очень просто для вас, ребята

use strict;
use warnings;

my $filename = 'info.text';
open my $info, $filename or die "Could not open $filename: $!";
my $first_line = 2;
my $last_line = 15;

open(FILE, $filename) or die "Could not read from $filename, program halting.";

my $count = 1;
my @lines;

while(<FILE>){
    if($count > $last_line){
        close FILE;
        exit;
    }
    if($count >= $first_line){
        #print $_;
        push @lines, $_;
    }
    $count++;
}
print @lines;
3 2

3 ответа:

Perl фактически имеет переменную $., которая представляет текущую строку из последнего используемого дескриптора файла:

Из perldoc -v $.:

HANDLE - >input_line_number (EXPR)

$INPUT_LINE_NUMBER

$NR

$.

Номер текущей строки для последнего доступного файла.

Каждая файловая ручка в Perl подсчитывает количество прочитанных строк. от него. (В зависимости от значения$/, представление Perl о том, что составляет линия может не совпадать с вашей.) Когда строка читается из filehandle (через readline () или ), или когда tell () или seek () вызывается на нем, $. становится псевдонимом для счетчика строк для этой файловой ручки.

Эту переменную можно использовать для радикального упрощения кода:

use strict;
use warnings;

my $filename = 'info.text';
open(FILE, $filename) 
   or die "Could not read from $filename, program halting.";

my @lines;
while(<FILE>){
    next unless $. >= 2 && $. <= 15;
    push @lines, $_;
}
close FILE;
print @lines;

Вы можете обернуть этот код или модифицированную версию в подпрограмму, которая принимает файловую ручку, начальную строку и конечную строку, чтобы сделать ее более гибкой.

Еще одна заметка, не связанная с вашим проблема под рукой, рекомендуется, чтобы вы всегда использовали три аргумента open .

Гораздо проще сделать это численно:

my @lines = (<FILE>)[1..14];

(примечание - perl массивы начинаются с нуля - ваша "первая" строка 0 в приведенном выше)

Но вы можете альтернативно сохранить то, что вы делаете, и проверить $.:

while ( my $line = <FILE> ) {
    chomp; 
    next unless $. > 2; 
    push ( @lines, $line ); 
    last if $. > 15; 
}

Что должно было бы сделать то же самое.

На самом деле в вашем коде очень мало ошибок. Единственная причина, по которой он не работает, заключается в том, что вы вызываете exit, когда последняя строка диапазона была найдена. Это означает, что программа немедленно останавливается и никогда не выполняет оператор print @lines

Вы также открываете входной файл дважды без видимой причины, но это не вызывает никаких проблем

Вот как бы я написал это. Обратите внимание, что я использовал autodie pragma, так что мне не нужно явно кодировать обработчики ошибок для любого из IO операции

use strict;
use warnings;
use v5.14.1;
use autodie;

use constant FILE       => 'info.text';
use constant FIRST_LINE => 2;
use constant LAST_LINE  => 15;

open my $fh, '<', FILE;

my @lines;

while ( <$fh> ) {
    push @lines, $_ if FIRST_LINE .. LAST_LINE;
    last if $. == LAST_LINE;
}

print @lines;