Хранение строк файла в массиве
Так что я довольно новичок в 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 ответа:
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;