Давайте начнем с просмотра вашего кода.
open(file_E, $file_E);
while ( <file_E> ) {
/([^\n]*)/;
print $line1;
}
close($file_E);
В первой строке вы открываете файл с именем в $file_E
, используя дескриптор файла голого слова file_E
. Это должно работать, пока файл успешно открывается. Также было бы лучше проверить успешность этой операции одним из двух способов: либо поместите use autodie;
в начало вашего скрипта (но затем рискуйте применить его семантику в тех местах, где ваш код несовместим с этим уровнем обработки ошибок), или измените свой open
, чтобы он выглядел так:
open(file_E, $file_E) or die "Failed to open $file_E: $!\n";
Теперь, если вам не удалось открыть файл, вы получите сообщение об ошибке, которое поможет отследить проблему.
Далее давайте посмотрим на цикл while
, потому что именно здесь у вас есть проблема, которая вызывает ошибку, с которой вы столкнулись. В первой строке цикла while
вы видите это:
while ( <file_E> ) {
Консультируясь с perldoc perlsyn
, вы увидите, что эта строка специально для этого сделана:
while (defined($_ = <file_E>)) {
Таким образом, ваш код неявно присваивает каждой строке $_
на последовательных итерациях. Также, посоветовавшись с perldoc perlop
, вы обнаружите, что когда вызывается оператор сопоставления (/.../
или m/.../
) без явной привязки сопоставления с использованием =~
, сопоставление сопоставляется с $_
, Тем не менее, пока все хорошо. Тем не менее, вы не делаете ничего полезного в матче. Оператор совпадения вернет логическую истину / ложь, если совпадение было успешным. А поскольку ваш шаблон содержит круглые скобки, он будет записывать что-то в переменную захвата $1
. Но вы никогда не проверяете успех матча, и при этом вы никогда больше не ссылаетесь на $1
.
В следующей строке вы делаете это: print $line1
. Где, в вашем коде, $line1
присваивается значение? Потому что ему никогда не присваивается значение в том, что вы нам показали.
Я могу только догадываться, что ваше намерение состоит в том, чтобы перебрать строки файла, захватить строку, но без завершающего символа новой строки, а затем распечатать ее. Кажется, что вы хотите напечатать его без каких-либо новых строк, чтобы весь входной файл печатался как одна строка вывода.
open my $input_fh_e, '<', $file_E or die "Failed to open $file_E: $!\n";
while(my $line = <$input_fh_e>) {
chomp $line;
print $line;
}
close $input_fh_e or die "Failed to close $file_E: $!\n";
Не нужно ничего захватывать - если все, что делает захват, это просто захват всего до новой строки, вы можете просто удалить новую строку с помощью chomp
для начала.
В моем примере я использовал лексический дескриптор файла (дескриптор файла с лексической областью, объявленный с my
). Как правило, это лучший метод в современном Perl, так как он избегает использования голого слова, избегает возможных коллизий пространства имен и гарантирует, что дескриптор закроется, как только закроется лексическая область.
Я также использовал версию «10 arg» open
, которая более безопасна, поскольку исключает возможность использования $file_E
для открытия канала или выполнения каких-либо других гнусных или просто непреднамеренных манипуляций с оболочкой.
Я предлагаю также запустить ваш скрипт с use strict;
, потому что если бы вы сделали это, вы получили бы сообщение об ошибке во время компиляции, сообщающее, что $line1
никогда не был объявлен. Также запустите ваш скрипт с use warnings
, чтобы вы могли получить предупреждение при попытке напечатать $line1
перед присвоением ему значения.
Большинство проблем в вашем коде будут обсуждаться в perldoc perlintro
, к которому вы можете обратиться из командной строки, просто набрав perldoc perlintro
, предполагая, что у вас установлен Perl. Обычно на чтение perlintro
уходит 20-40 минут. Если когда-либо существовал документ, который должен представлять собой обязательное чтение, прежде чем начать писать код на Perl, это чтение, вероятно, будет включать perlintro
.