открыть многострочный текстовый файл в perl

У меня есть следующий текстовый файл

Hello my
name is
Jeff

и я хочу открыть его с помощью perl. Однако при использовании этого кода

use strict;
use warnings;
open(my $fh, "<", "input.txt") or die "cannot open input text!";
my $text= <$fh>;
print $text;

Выходной текст только Hello my. Как я могу заставить его печатать все мои входные текстовые строки, а не только первую?


person JF Forget    schedule 16.01.2018    source источник


Ответы (2)


В скалярном контексте оценка дескриптора файла в угловых скобках дает следующую строку из этого файла.

поэтому вы можете использовать цикл while для чтения строк (предпочтительный метод)

while (<$fh>) #output will store into default variable $_
{
    print ; 

}

Или вы можете использовать массив, но вы пытаетесь сохранить все содержимое файла за раз в переменной

my @array = <$fh>;

И режим slurp для чтения всего файла в скалярной переменной

my $multiline = do { local $/; <$fh>; } #$/ input record seprator
person mkHun    schedule 16.01.2018
comment
Когда вы сохраняете дескриптор файла в скалярной переменной, она считывает следующую строку из файла Это не то, что происходит, когда вы сохраняете дескриптор файла в переменной. Возможно, когда вы вызываете readline для дескриптора файла. - person Borodin; 16.01.2018
comment
Когда вы сохраняете дескриптор файла в скалярную переменную, она считывает следующую строку из файла Или, точнее, в perldoc: в скалярном контексте вычисление дескриптора файла в угловых скобках дает следующую строку. из этого файла. - person Dave Cross; 16.01.2018
comment
@DaveCross и Бородин Спасибо за комментарий Сообщение отредактировано - person mkHun; 17.01.2018

Если вы прочитали раздел об операторах ввода-вывода в perldoc perlop вы увидите следующее:

В скалярном контексте оценка дескриптора файла в угловых скобках дает следующую строку из этого файла.

И, чуть ниже:

Если <FILEHANDLE> используется в контексте поиска списка, возвращается список, содержащий все входные строки, по одной строке на элемент списка.

Если вы присвоите <FILEHANDLE> скалярной переменной, вы получите следующую строку (фактически запись) из файла. Вот что вы делаете:

my $text = <$fh>;

Если вы присвоите <FILEHANDLE> массиву, вы получите все остальные данные из файла, причем каждая строка (фактически запись) находится в отдельном элементе массива.

my @text = <$fh>;

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

my $text = join '', <$fh>;

Вы можете использовать $/, чтобы изменить представление Perl о "записи" (часто делается в блоке do):

my $text = do { local $/; <$fh> };

Мне нравится метод slurp из Path::Tiny.

use Path::Tiny;

my $text = path($filename)->slurp;
person Dave Cross    schedule 16.01.2018