Как дать указание Perl рассматривать несколько строк, прерванных на определенном символе, как одну строку?

#perl #file

#perl #файл

Вопрос:

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

 command1

command2

execute myscript amp;
        opt1=val1 amp;
        opt2=val2

...
  

При открытии файла есть ли способ сообщить Perl, чтобы он рассматривал эти три строки, как если бы это была одна строка, и игнорировал amp; ?

Ответ №1:

Не при открытии файла. Но соединить их во время чтения не так уж сложно:

 open(my $in, '<', 'file.txt') or die;
while (<$in>) {
  $_ .= <$in> while s/amp;s*z//;

  # $_ now contains a complete record
  ...
}
  

Ответ №2:

Если у вас всегда есть несколько новых строк между записями, рассмотрите возможность использования разделителя записей для их чтения. Затем вы можете использовать быструю проверку на amp; и выполнить разделение / объединение:

 use English '-no_match_vars'; 

sub read_records {
    local $RS = "nn";  # or,  for the machoistic,  $/ works too without English
    ... # open the file
    while (my $record = <$fh>) {
        chomp $record;               # uses $RS for what to remove, nice!
        if ($record =~ /amp;s*$/ms) {  # amp; at the end of *any* line (w/only spaces)
            $record = join ' ', split /s*amp;s /, $record; # pull them out
        }
        ... # do something with the record
    }
}
  

Ответ №3:

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

 #! /usr/bin/env perl

use strict;
use warnings;

sub read_input {
  my($fh) = @_;
  local $/;
  scalar <$fh>;
}

my $commands = read_input *DATA;

$commands =~ s/amp;n//g;
print $commands;

__DATA__
command1

command2

execute myscript amp;
        opt1=val1 amp;
        opt2=val2
  

Вывод:

команда1

команда2

выполнить myscript opt1=val1 opt2=val2