2015-08-12 9 views
-1

Я пытаюсь в Perl выбрать одну полную строку из всего документа, содержащего «CURRENT_RUN_ID». Я использовал код ниже для выполнения вышеуказанной задачи, но я не могу войти в цикл while.Выбор конкретной строки с определенной строкой

my $sSuccessString = "CURRENT_RUN_ID"; 

open(LOG, "$slogfile") or die("Can't open $slogfile\n"); 
my $sLines; 
{ 
    local $/ = undef; 
    $sLines=<LOG>; 
} 
my $spool = 0; 
my @matchingLines; 

while (<LOG>) 
{ 
    print OUTLOG "in while loop\n"; 

    if (m/$sSuccessString/i) { 
     print OUTLOG "in if loop\n"; 
     $spool = 1; 
     print map { "$_ \n" } @matchingLines; 
     @matchingLines =(); 
    } 
    if ($spool) { 
     push (@matchingLines, $_); 
    } 
} 
+2

Когда я вижу переменную '$ sSuccessString', все, что я могу собрать это«*** nooooooooo !!! ***»На самом деле, вы нарушаете дух венгерской нотации. Все в Perl может быть сжато ... поэтому вам не нужно два напоминания о том, что переменная представляет собой строку с префиксом 's' и суффикс' String'. Вместо этого 'my $ success_re = qr/CURRENT_RUN_ID/i;' или 'my $ log_fname = ...' будет фактически соответствовать *** духу *** венгерской нотации. –

ответ

4

Вы уже сделали чтение из дескриптора LOG после того как вы отхлебнул его в $sLines. <LOG> в начале while вернет undef, потому что он достиг eof. Вы либо должны использовать эту переменную $sLines в своем цикле while, либо избавиться от него. Вы все равно не используете его.

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

use strict; 
use warnings; 

open my $fh_in, '<', 'input_file' or die $!; 
open my $fh_out '>', 'output_file' or die $!; 

while (my $line = <$fh_in>) { 
    print $fh_out $line if $line =~ m/CURRENT_RUN_ID/; 
} 

close $fh_in; 
close $fh_out; 
+0

Привет, Simbabque, я попытался реализовать ваш код, сохраняя «$ slogfile» в качестве входного файла и новое имя для файла output_file, но получение (исключение из-за ошибки «output_file» при строгих подписях). пожалуйста, предложите – Sur

+0

@Sur, это синтаксическая ошибка. Вероятно, вы забыли либо '' 'имя переменной, либо процитировать имя файла. Просто прочитайте строку, на которую указывает сообщение. Это будет довольно очевидно. ;) – simbabque

1

При выполнении этого кода:

$sLines=<LOG>; 

он считывает все данные из LOG в $sLines и он оставляет указатель файла для LOG в конце файла. Поэтому, когда вы в следующий раз попробуйте прочитать из этого дескриптора файла с:

while (<LOG>) 

ничего не возвращается, как нет больше данных для чтения.

Если вы хотите прочитать файл дважды, вам нужно будет использовать функцию seek(), чтобы сбросить указатель файла до вашего второго чтения.

seek LOG, 0, 0; 

Но, учитывая, что вы ничего с $sLines я подозреваю, что вы, вероятно, можете просто удалить, что целый раздел коды не делаете.

Все это с $spool и @matchingLines кажется странным. Что вы пытались достичь там?

Я думаю, что ваш код может быть упрощен просто:

my $sSuccessString = "CURRENT_RUN_ID"; 

open(LOG, $slogfile) or die("Can't open $slogfile\n"); 

while (<LOG>) { 
    print OUTLOG if /$sSuccessString/i/; 
} 

Лично я хотел бы сделать это еще проще, путем чтения из STDIN и записи в STDOUT.

my $sSuccessString = 'CURRENT_RUN_ID'; 

while (<>) { 
    print if /$sSuccessString/i/; 
} 

А затем с использованием перенаправления ввода-вывода Unix для подключения правильных файлов.

$ ./this_filter.pl <your_input.log> your_output.log 
Смежные вопросы