Perl Language
Чтение содержимого файла в переменную
Поиск…
Ручной способ
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