Поиск…


Ручной способ

open my $fh, '<', $filename
    or die "Could not open $filename for reading: $!";
my $contents = do { local $/; <$fh> };

После открытия файла (прочитайте man perlio если вы хотите читать определенные кодировки файлов вместо необработанных байтов), трюк находится в блоке do : <$fh> , дескриптор файла в алмазном операторе, возвращает одну запись из файла , Переменная «input record separator» $/ указывает, что такое «запись» - по умолчанию она установлена ​​на символ новой строки, поэтому «запись» означает «одна строка». Поскольку $/ - глобальная переменная, local выполняет две вещи: создает временную локальную копию $/ которая будет исчезать в конце блока, и дает ему (не) значение undef (значение, которое Perl дает к неинициализированным переменным). Когда разделитель входных данных имеет это (не) значение, оператор алмаза вернет весь файл. (Он рассматривает весь файл как одну строку.)

Используя do , вы можете даже вручную открыть файл. Для повторного чтения файлов,

sub readfile { do { local(@ARGV,$/) = $_[0]; <> } }
my $content = readfile($filename);

может быть использован. Здесь другая глобальная переменная ( @ARGV ) локализована для моделирования того же процесса, который используется при запуске скрипта perl с параметрами. $/ все еще undef , так как массив перед ним «ест» все входящие аргументы. Затем оператор алмаза <> снова поставляет одну запись, определяемую $/ (весь файл), и возвращает из блока do , которые, в свою очередь, возвращаются из суб.

Sub не имеет явной обработки ошибок, что является плохой практикой! Если во время чтения файла возникает ошибка, вы получите undef как возвращаемое значение, а не пустую строку из пустого файла.

Другим недостатком последнего кода является тот факт, что вы не можете использовать PerlIO для разных кодировок файлов - вы всегда получаете необработанные байты.

Путь :: Крошечный

Использование идиомы из Manual Way несколько раз в сценарии скоро становится утомительным, поэтому вы можете попробовать модуль.

use Path::Tiny;
my $contents = path($filename)->slurp;

Вы можете передать опцию binmode если вам нужно контролировать кодировки файлов, окончания строк и т. Д. - см. man perlio :

my $contents = path($filename)->slurp( {binmode => ":encoding(UTF-8)"} );

Path::Tiny также имеет множество других функций для работы с файлами, поэтому он может быть хорошим выбором.

Файл :: Slurper

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

use File::Slurper 'read_text';
my $contents = read_text($filename);

read_text() принимает два необязательных параметра для указания кодировки файла и должны ли переводы строк быть переведены между стандартами UNIX Unixish или DOSish CRLF:

my $contents = read_text($filename, 'UTF-8', 1);

Файл :: Slurp

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

Разбиение файла на переменную массива

open(my $fh, '<', "/some/path") or die $!;
my @ary = <$fh>;

При оценке в контексте списка оператор алмаза возвращает список, состоящий из всех строк в файле (в этом случае присваивание результата контексту списка источников массива). Терминатор линии сохраняется и может быть удален путем прерывания:

chomp(@ary); #removes line terminators from all the array elements.

Файл Slurp в одном слое

Разделитель входных данных может быть задан с помощью ключа -0 ( ноль , а не капитала O ). В качестве значения берется восьмеричное или шестнадцатеричное число. Любое значение 0400 или выше приведет к тому, что Perl будет клонировать файлы, но, по договоренности, значение, используемое для этой цели, составляет 0777 .

perl -0777 -e 'my $file = <>; print length($file)' input.txt

Идя далее с минимализмом, указание -n switch заставляет Perl автоматически читать каждую строку (в нашем случае - весь файл) в переменную $_ .

perl -0777 -ne 'print length($_)' input.txt


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow