perl чтение файла и захват определенных строк

У меня есть текстовый файл, и я хочу получить определенные строки, начинающиеся с шаблона и заканчивающиеся определенным шаблоном. Пример:

Text
Text
Startpattern
print this line
Print this line
print this line
Endpattern
Text
Text
Text

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


my $LOGFILE = "/var/log/logfile";
my @array;
# open the file (or die trying)

open(LOGFILE) or die("Could not open log file.");
foreach $line () {
  if($line =~  m/Sstartpattern/i){
    print $line;
    foreach $line2 () {
      if(!$line =~  m/Endpattern/i){
        print $line2;
      }
    }
  }
}
close(LOGFILE);

Заранее спасибо за вашу помощь.


person JohnDoe    schedule 22.03.2011    source источник
comment
Я знаю, что в глубине души, когда вы написали «Не удалось открыть файл журнала», вы хотели написать «Не удалось открыть $LOGFILE: $!».   -  person William Pursell    schedule 22.03.2011


Ответы (3)


Как насчет этого:

#!perl -w
use strict;

my $spool = 0;
my @matchingLines;

while (<DATA>) {
    if (/StartPattern/i) {
        $spool = 1;
        next;
    }
    elsif (/Endpattern/i) {
        $spool = 0;
        print map { "$_ \n" } @matchingLines;
        @matchingLines = ();
    }
    if ($spool) {
        push (@matchingLines, $_);
    }
}

__DATA__

Text
Text
Startpattern
print this line
Print this line
print this line
Endpattern
Text
Text
Text
Startpattern
print this other line
Endpattern

Если вы хотите, чтобы начальный и конечный шаблоны также были напечатаны, добавьте операторы push в этот блок if.

person Bee    schedule 22.03.2011
comment
Идеальный. Большое тебе спасибо. Теперь у меня есть только одна проблема :-) Как я могу установить динамические имена массивов и распечатать каждый массив после того, как я захватил в него все совпадающие строки? - person JohnDoe; 22.03.2011
comment
Я довольно новичок в perl и не совсем понял вопрос. Если вы можете объяснить немного подробнее, каковы ваши требования, я мог бы помочь. - person Bee; 23.03.2011

Вы можете использовать скалярный оператор диапазона:

open my $fh, "<", $file or die $!;

while (<$fh>) {
    print if /Startpattern/ .. /Endpattern/;
}
person Eugene Yarmash    schedule 22.03.2011
comment
Привет, это звучит довольно хорошо, но у меня есть несколько групп с начальными и конечными шаблонами. - person JohnDoe; 22.03.2011
comment
@Tester: скаляр .. должен работать для любого количества групп в файле - person Eugene Yarmash; 22.03.2011

Что-то вроде этого?

my $LOGFILE = "/var/log/logfile";
open my $fh, "<$LOGFILE" or die("could not open log file: $!");
my $in = 0;

while(<$fh>)
{
    $in = 1 if /Startpattern/i;
    print if($in);
    $in = 0 if /Endpattern/i;
}
person jho    schedule 22.03.2011
comment
К сожалению, печатает только строку, соответствующую стартовому шаблону. Мне нужно распечатать начальный шаблон, текст между начальным и конечным шаблонами, а также конечный шаблон. У меня есть несколько групп с startpattern, text, text, text, endpattern - person JohnDoe; 22.03.2011
comment
Извините моя ошибка. Я забыл удалить строку. Как я могу сгруппировать эти записи в несколько массивов? - person JohnDoe; 22.03.2011
comment
Я также работаю над подобными вещами, но решение, упомянутое Евгением-у, также печатает начальный и конечный шаблоны, которые нам не нужны, как мы можем их отрицать, пожалуйста, предложите. - person XYZ_Linux; 22.10.2013