В Perl, как я могу считать весь файл в строку?

Просто используйте ссылку на функцию:

def pwr(x, y):
    return x ** y

def add(x, y):
    return x + y

dispatcher = { 'pwr' : pwr, 'add' : add}

def call_func(x, y, func):
    try:
        return dispatcher[func](x, y)
    except:
        return "Invalid function"

call_func(2, 3, 'add')

Простой и безопасный.

113
задан 13 revs, 9 users 35% 12 January 2014 в 04:17
поделиться

8 ответов

Добавьте:

 local $/;

перед чтением из дескриптора файла. См. Как я могу прочитать весь файл сразу? или

$ perldoc -q "entire file"

См. Переменные, связанные с дескрипторами файлов в perldoc perlvar и perldoc - f local .

Между прочим, если вы можете разместить свой сценарий на сервере, у вас могут быть все модули, которые вам нужны. См. Как мне сохранить свой собственный каталог модулей / библиотек? .

Кроме того, Path :: Class :: File позволяет slurp и spew .

Path :: Tiny предоставляет еще более удобные методы, такие как slurp , slurp_raw , slurp_utf8 , а также их изрыгают аналогов.

77
ответ дан 24 November 2019 в 02:37
поделиться

Вы можете сохранить отметку для первой экранной строки, отображаемой в окне, и восстановить ее. Пример, который выполняет команду g? для всего буфера и восстанавливает обе позиции:

:noremap <F11> mkHmlggg?G`lzt`k

Выполнение команды:

  • mk : установить метку k для текущая позиция
  • H : перейти к первой строке на экране
  • ml : установить метку l для этой позиции
  • ggg? G : выполнить команда
  • `l :
7
ответ дан 24 November 2019 в 02:37
поделиться

Все сообщения немного неидиоматичны. Идиома такая:

open my $fh, '<', $filename or die "error opening $filename: $!";
my $data = do { local $/; <$fh> };

В большинстве случаев нет необходимости устанавливать для $ / значение undef .

49
ответ дан 24 November 2019 в 02:37
поделиться

С File :: Slurp :

use File::Slurp;
my $text = read_file('index.html');

Да, даже вы можете использовать CPAN .

75
ответ дан 24 November 2019 в 02:37
поделиться

Я бы сделал это так:

my $file = "index.html";
my $document = do {
    local $/ = undef;
    open my $fh, "<", $file
        or die "could not open $file: $!";
    <$fh>;
};

Обратите внимание на использование версии open с тремя аргументами. Это намного безопаснее, чем старые версии с двумя (или одним) аргументами. Также обратите внимание на использование лексического дескриптора файла. Лексические дескрипторы файлов лучше, чем старые варианты с голым словом, по многим причинам. Здесь мы пользуемся преимуществом одного из них: они закрываются, когда выходят из поля зрения.

94
ответ дан 24 November 2019 в 02:37
поделиться

Простой способ:

while (<FILE>) { $document .= $_ }

Другой способ - изменить разделитель входной записи «$ /». Вы можете сделать это локально в пустом блоке, чтобы избежать изменения глобального разделителя записей.

{
    open(F, "filename");
    local $/ = undef;
    $d = <F>;
}
7
ответ дан 24 November 2019 в 02:37
поделиться

Из perlfaq5: Как я могу прочитать весь файл сразу? :


Вы можете использовать модуль File :: Slurp, чтобы сделать это за один шаг.

use File::Slurp;

$all_of_it = read_file($filename); # entire file in scalar
@all_lines = read_file($filename); # one line per element

Обычный подход Perl для обработки всех строк в файле состоит в том, чтобы делать это по одной строке за раз:

open (INPUT, $file)     || die "can't open $file: $!";
while (<INPUT>) {
    chomp;
    # do something with $_
    }
close(INPUT)            || die "can't close $file: $!";

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

@lines = <INPUT>;

, вы должны хорошо подумать, зачем вам нужно все загружать сразу. Это просто не масштабируемое решение. Вам также может быть интереснее использовать стандартный Tie :: Файловый модуль или привязки $ DB_RECNO модуля DB_File, которые позволяют привязать массив к файлу, чтобы при доступе к элементу массив фактически обращался к соответствующей строке в файле.

Вы можете прочитать все содержимое дескриптора файла в скаляр .

{
local(*INPUT, $/);
open (INPUT, $file)     || die "can't open $file: $!";
$var = <INPUT>;
}

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

$var = do { local $/; <INPUT> };

Для обычных файлов вы также можете использовать функцию чтения.

read( INPUT, $var, -s INPUT );

Третий аргумент проверяет размер байта данных на файловом дескрипторе INPUT и считывает это количество байтов в буфер $ var.

{
local(*INPUT, $/);
open (INPUT, $file)     || die "can't open $file: $!";
$var = <INPUT>;
}

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

$var = do { local $/; <INPUT> };

Для обычных файлов вы также можете использовать функцию чтения.

read( INPUT, $var, -s INPUT );

Третий аргумент проверяет размер байта данных на файловом дескрипторе INPUT и считывает это количество байтов в буфер $ var.

{
local(*INPUT, $/);
open (INPUT, $file)     || die "can't open $file: $!";
$var = <INPUT>;
}

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

$var = do { local $/; <INPUT> };

Для обычных файлов вы также можете использовать функцию чтения.

read( INPUT, $var, -s INPUT );

Третий аргумент проверяет размер байта данных на файловом дескрипторе INPUT и считывает это количество байтов в буфер $ var.

18
ответ дан 24 November 2019 в 02:37
поделиться

Вы получаете только первую строку от оператора ромба , потому что вы оцениваете ее в скалярном контексте:

$document = <FILE>; 

В контексте списка / массива, оператор ромба вернет все строки файла.

@lines = <FILE>;
print @lines;
3
ответ дан 24 November 2019 в 02:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: