Я пытаюсь открыть файл .html как одну большую длинную строку. Вот что у меня есть:
open(FILE, 'index.html') or die "Can't read file 'filename' [$!]\n";
$document = <FILE>;
close (FILE);
print $document;
что приводит к:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN
Однако я хочу, чтобы результат выглядел так:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
Таким образом, мне будет проще искать по всему документу.
Ответы:
Добавить:
перед чтением из дескриптора файла. См. Как я могу прочитать весь файл сразу? , или
Смотрите Переменные, связанные с дескрипторами файлов в
perldoc perlvar
иperldoc -f local
.Между прочим, если вы можете разместить свой скрипт на сервере, у вас могут быть все модули, которые вам нужны. См. Как сохранить свой собственный каталог модулей / библиотек? ,
Кроме того, Path :: Class :: File позволяет вам чавкать и извергать .
Путь :: Крошка дает еще более удобные методы , такие как
slurp
,slurp_raw
,slurp_utf8
а также ихspew
коллеги.источник
$/
, вам, вероятно, следует добавить ссылки для получения дополнительной информации.local
а неmy
.Я бы сделал так:
Обратите внимание на использование версии open с тремя аргументами. Это намного безопаснее, чем старые версии с двумя (или одним) аргументами. Также обратите внимание на использование лексического дескриптора файла. Лексические дескрипторы файлов лучше, чем старые варианты с голым словом, по многим причинам. Здесь мы пользуемся преимуществом одного из них: они закрываются, когда выходят за рамки.
источник
С File :: Slurp :
Да, даже вы можете использовать CPAN .
источник
Can't locate File/Slurp.pm in @INC (@INC contains: /usr/lib/perl5/5.8/msys
:(Все сообщения немного не идиоматичны. Идиома такая:
В большинстве случаев нет необходимости устанавливать $ / в значение
undef
.источник
local $foo = undef
это просто рекомендованный метод Perl Best Practice (PBP). Если мы публикуем фрагменты кода, я бы подумал, что сделать все возможное, чтобы прояснить это, было бы неплохо.Из perlfaq5: Как я могу прочитать весь файл сразу? :
Вы можете использовать модуль File :: Slurp, чтобы сделать это за один шаг.
Обычный подход Perl для обработки всех строк в файле - делать это по одной строке за раз:
Это намного эффективнее, чем чтение всего файла в память в виде массива строк с последующей обработкой его по одному элементу за раз, что часто - если не почти всегда - является неправильным подходом. Когда вы видите, что кто-то делает это:
Вам следует долго и серьезно подумать, зачем вам все загружать сразу. Это просто не масштабируемое решение. Вы также можете найти более интересным использование стандартного модуля Tie :: File или привязок $ DB_RECNO модуля DB_File, которые позволяют привязать массив к файлу, чтобы при доступе к элементу массив фактически имел доступ к соответствующей строке в файле. ,
Вы можете прочитать все содержимое дескриптора файла в скаляр.
Это временно отменяет ваш разделитель записей и автоматически закрывает файл при выходе из блока. Если файл уже открыт, просто используйте это:
Для обычных файлов вы также можете использовать функцию чтения.
Третий аргумент проверяет размер байта данных в дескрипторе файла INPUT и считывает это количество байтов в буфер $ var.
источник
Простой способ:
Другой способ - изменить разделитель входной записи «$ /». Вы можете сделать это локально в пустом блоке, чтобы избежать изменения глобального разделителя записей.
источник
{local $/; open(my $f, '<', 'filename'); $d = <$f>;}
open
или неявно вызванныйclose
.my $d = do{ local $/; open(my $f, '<', 'filename') or die $!; my $tmp = <$f>; close $f or die $!; $tmp}
, (Проблема в том, что кодировка ввода не указана.)use autodie
, главное улучшение, которое я хотел показать, - это лексический дескриптор файла и 3 аргумента open. Есть какая-то причина, по которой вы это делаетеdo
? почему бы просто не выгрузить файл в переменную, объявленную перед блоком?Либо набор
$/
дляundef
(см ответа jrockway) , или просто сцепить все строки к файлу:Рекомендуется использовать скаляры для дескрипторов файлов в любой версии Perl, которая его поддерживает.
источник
Другой возможный способ:
источник
Вы получаете только первую строку от оператора ромба,
<FILE>
потому что оцениваете ее в скалярном контексте:В контексте списка / массива оператор «ромб» вернет все строки файла.
источник
<=>
а<>
оператор ромба.Я бы сделал это самым простым способом, чтобы любой мог понять, что происходит, даже если есть более разумные способы:
источник
<f>
- возвращает массив строк из нашего файла (если$/
имеет значение по умолчанию"\n"
) и затемjoin ''
вставляет этот массив в.источник
Это скорее предложение, как этого НЕ делать. Мне просто не удалось найти ошибку в довольно большом Perl-приложении. У большинства модулей были собственные файлы конфигурации. Чтобы прочитать файлы конфигурации в целом, я нашел одну строку Perl где-то в Интернете:
Он переназначает разделитель строк, как объяснялось ранее. Но он также переназначает STDIN.
У этого был по крайней мере один побочный эффект, поиск которого стоил мне часов: он не закрывает неявный дескриптор файла должным образом (поскольку он не вызывает
close
вообще).Например, так:
приводит к:
Странно то, что счетчик строк
$.
увеличивается для каждого файла на единицу. Он не сбрасывается и не содержит количества строк. И он не сбрасывается в ноль при открытии другого файла, пока не будет прочитана хотя бы одна строка. В моем случае я делал что-то вроде этого:Из-за этой проблемы условие было ложным, потому что счетчик строк не был сброшен должным образом. Не знаю, ошибка это или просто неправильный код ... Также вызов
close;
oderclose STDIN;
не помогает.Я заменил этот нечитаемый код, используя open, конкатенацию строк и close. Однако решение, опубликованное Брэдом Гилбертом, также работает, поскольку вместо этого используется явный дескриптор файла.
Три строки в начале можно заменить на:
который правильно закрывает дескриптор файла.
источник
использование
раньше
$document = <FILE>;
.$/
- разделитель входных записей , по умолчанию - новая строка. Переопределяя его наundef
, вы говорите, что разделителя полей нет. Это называется режимом «отхлебки».Другие решения, такие как
undef $/
иlocal $/
(но неmy $/
) повторно объявляют $ / и, таким образом, производят тот же эффект.источник
Вы можете просто создать подпрограмму:
источник
Я не знаю, хорошая ли это практика, но я использовал это:
источник
Все это хорошие ответы. НО, если вы чувствуете себя ленивым, и файл не такой уж большой, а безопасность не является проблемой (вы знаете, что у вас нет испорченного имени файла), вы можете выполнить раскладку:
источник
Вы можете использовать cat в Linux:
источник