скрипт perl для чтения содержимого между отметками - PullRequest
1 голос
/ 06 ноября 2011

В perl, как прочитать содержимое между двумя метками. Исходные данные как это

START_HEAD
ddd
END_HEAD

START_DATA
eee|234|ebf
qqq|              |ff
END_DATA

--Generate at 2011:23:34

тогда я хочу получить данные только между "START_DATA" и "END_DATA". Как это сделать?

sub readFile(){ 
    open(FILE, "<datasource.txt") or die "file is not found";

    while(<FILE>){      
        if(/START_DATA/){           
            record(\*FILE);#start record;
        }
    }
}

sub record($){
    my $fileHandle = $_[0];

    while(<fileHandle>){
        print $_."\n";      
        if(/END_DATA/) return ;         
    }
}

Я пишу этот код, он не работает. ты знаешь почему?

Спасибо

Спасибо

Ответы [ 3 ]

6 голосов
/ 06 ноября 2011

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

perl -ne 'print if /START_DATA/ .. /END_DATA/'

Вывод также будет содержать строки * _DATA, но избавиться от них не составит большого труда.

3 голосов
/ 06 ноября 2011

Помимо нескольких опечаток, ваш код не слишком далеко.Если бы вы использовали

use strict;
use warnings;

Возможно, вы поняли это сами.Вот что я нашел:

  • Не используйте прототипы, если они вам не нужны, или не знаете, что они делают.

Обычное подчиненное объявление - sub my_function (prototype) {, ноВы можете опустить прототип и просто использовать sub my_function {.

  • while (<fileHandle>) { отсутствует знак $, чтобы обозначить, что это переменная (скалярная), а не глобальная.Должно быть $fileHandle.
  • print $_."\n"; добавит дополнительный перевод строки.Просто print; будет делать то, что вы ожидаете.
  • if(/END_DATA/) return; - синтаксическая ошибка.В этом случае скобки не являются обязательными в perl.Если вы не переверните утверждение.

Используйте:

return if (/END_DATA/);

или

if (/END_DATA/) { return }

Ниже приведена очищенная версия.Я прокомментировал ваш open() во время тестирования, так что это будет пример функционального кода.

use strict;
use warnings;

readFile();

sub readFile { 
    #open(FILE, "<datasource.txt") or die "file is not found";
    while(<DATA>) {      
        if(/START_DATA/) {
            recordx(\*DATA); #start record;
        }
    }
}

sub recordx {
    my $fileHandle = $_[0];
    while(<$fileHandle>) {
        print;
        if (/END_DATA/) { return }         
    }
}

__DATA__
START_HEAD
ddd
END_HEAD

START_DATA
eee|234|ebf
qqq|              |ff
END_DATA

--Generate at 2011:23:34
0 голосов
/ 06 ноября 2011

Это довольно просто сделать с регулярными выражениями, просто используйте флаги / s или / m (однострочные или многострочные) - / s позволяет оператору . сопоставлять строки, поэтому вы можете сделать /start_data(.+)end_data/is.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...