В Perl, как я "slurp" содержимое нескольких файлов в строку?

У Perl есть много удобных идиом для простых вещей, в том числе:

  • Оператор чтения файлов <HANDLE>, если он используется без дескриптора файла, будет легко открывать и читать все файлы в @ARGV, по одной строке за раз:

    while (<>) { print $., $_;  }
    
  • Посредством (локально) сброса разделителя входных записей $/ я могу сразу "разбить" весь файл:

    local $/; $content = <HANDLE>;
    

Но эти две идиомы работают не так, как я ожидал: после того, как я reset $/, разрывы с <> останавливаются в конце файла: Ниже приводится только содержимое первого файла.

local $/; $content = <>;

Теперь я верю, что это поведение должно быть по дизайну, но мне все равно. Какая краткая идиома Perl для получения всего содержимого всех файлов в строку? (В этом связанном вопросе упоминается способ разбить список файлов на отдельные строки, что является началом... но не очень элегантным, если вам все равно нужно присоединиться к строкам впоследствии.)

Ответ 1

Вы понимаете, что вы скрываете только несколько вызовов open, правильно? Там нет волшебного способа читать несколько файлов, не открывая их по очереди

Как вы уже нашли, Perl перестанет читать в конце каждого файла, если для параметра $/ установлено значение undef

Внутренний механизм, который обрабатывает <>, удаляет каждое имя файла из @ARGV по мере его открытия, поэтому я предлагаю вам просто использовать цикл while, который читает с использованием <>, пока @ARGV не будет пустым

Это будет выглядеть как

use strict;
use warnings 'all';

my $data;
{
    local $/;
    $data .= <> while @ARGV;
}

Ответ 2

Так как, похоже, не существует способа полностью разбить все, одно компактное решение - разместить <> в контексте списка. Неявные повторные вызовы будут извлекать все.

local $/;
$data = join "", <>;

Ответ 3

use File::Slurp qw/read_file/;
my $text = read_file( 'filename' ) ;