2015-02-06 3 views
0

У меня есть alog с сервера приложений, мне нужно получить строку с флагом «E» или «W», если есть строка после выведенной строки, мне тоже нужно ее получить.Как разобрать конкретные строки в perl?

Я пытаюсь выяснить, сценарий:

#!/usr/bin/perl 
use strict; 
use warnings; 

my $msg; 
my $line; 
my $line2; 
main(@ARGV); 

sub rec { 
    #$msg= $line; 
    print $line; 
    while ($line2 = <FH>) { 
     if ($line2 !~ m/^\[/){ 
      #$msg = $msg.$line2; 
      print $line2; 
     } else { 
      if($line2 =~ m/ E | W /) { rec(); } 
      last; 
     } 

    } 
    #print $msg; 
} 
sub main { 
    open(FH,'SystemOut_15.02.05_17.00.02.log') or die "Error openong file : $!"; 
    while ($line = <FH>) { 
     if($line =~ m/ E | W/and $line =~ m/^\[/){ 
       rec(); 
     } 
    } 
    close FH; 
    } 

Спасибо заранее.

образец журнала:

[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S 
QLState: null 
*********************************************************** Start Server ******************************* 
0000003a JDBCException O OK 
0000003a JDBCException O OK 
********************************************************** End Server ******************************* 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S 
QLState: null 
                org.hibernate.util.JDBCExceptionReporter 
                org.hibernate.util.JDBCExceptionReporter 
                org.hibernate.util.JDBCExceptionReporter 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S 
QLState: null 
                org.hibernate.util.JDBCExceptionReporter 
                org.hibernate.util.JDBCExceptionReporter 
                org.hibernate.util.JDBCExceptionReporter 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S 
QLState: null 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S 
QLState: null 
                org.hibernate.util.JDBCExceptionReporter 
                org.hibernate.util.JDBCExceptionReporter 
                org.hibernate.util.JDBCExceptionReporter 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK 

Что мне нужно получить:

[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S 
QLState: null 
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, SQLState: null 
                 org.hibernate.util.JDBCExceptionReporter 
                 org.hibernate.util.JDBCExceptionReporter 
                 org.hibernate.util.JDBCExceptionReporter 
    [2/5/15 14:55:18:025 UTC] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, SQLState: null 
                 org.hibernate.util.JDBCExceptionReporter 
                 org.hibernate.util.JDBCExceptionReporter 
                 org.hibernate.util.JDBCExceptionReporter 
    [2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, SQLState: null 
    [2/5/15 14:55:18:025 UTC] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, SQLState: null 
                 org.hibernate.util.JDBCExceptionReporter 
                 org.hibernate.util.JDBCExceptionReporter 
                 org.hibernate.util.JDBCExceptionReporter 

один сильный способ игнорировать линии между началом и остановки использовать триггер, как указано ysth; другой (слабый) метод:

open(my $fh, '<', 'test2.log') or die "Error opening file : $!"; 
my $match = 0; 
while (my $line = <$fh>) { 
    if ($line =~ /^\*+/){ 
     $match = 0; ## initialize match if line start with star 
    } 
    if ($line =~ /^\[/) { 
      $match = $line =~ m/ E | W /; 
    } 
    print $line if $match; 
} 
close $fh; 
+0

строка, обозначающая одну строку (и перестать смотреть, когда вы ее найдете)? можете ли вы объяснить, что должен делать ваш код? это кажется намного сложнее, чем ваше описание того, что вы хотите – ysth

+0

можете ли вы дать образец ввода и что вы ожидаете извлечь? – Sobrique

+0

@ ysth/@Sobrique: Нет, он ищет все вхождения для шаблона –

ответ

2

Pretty simple; вам просто нужно следить, являетесь ли вы в настоящее время в рамках согласование многострочной записи, и использовать flipflop operator (scalar context ..) исключить диапазоны сервера начала/конца строки:

open(my $fh, '<', 'SystemOut_15.02.05_17.00.02.log') or die "Error opening file : $!"; 
my $match = 0; 
while (my $line = <$fh>) { 
    unless ($line =~ /^\*+ Start Server \*+$/ .. $line =~ /^\*+ End Server \*+$/) { 
     if ($line =~ /^\[/) { 
      $match = $line =~ m/ E | W /; 
     } 
     print $line if $match; 
    } 
} 
close $fh; 
+0

Привет, спасибо за код, но он не принимает во внимание –

+0

Привет, спасибо за код, но он не принимает во внимание, если он начинается с: 'code' [2/5/15 14:55:18: 025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions Ошибка SQL: 17006, S QLState: null ************************* ********************************** Начать сервер ************** ***************** 0000003a JDBCException O OK 0000003a JDBCException O OK [2/5/15 14: 55: 18: 025 UTC] 0000003a JDBCException W org.hibernate. Util.JDBCExceptionReporter logExceptions Ошибка SQL: 17006, S QLState: null 'code' –

+0

Я не уверен, что вы имеете в виду; можете ли вы поместить это в свой образец ввода (и вывод, если он должен быть включен?) – ysth

1

Вы, вероятно, полезно прочитать хорошее образцы кода, предоставленные хорошими парнями POE :: Wheel :: FollowTail, доступными на Watching Logs и Tail following web server.

Как ваш файл журнала имеет многострочные записи, ваша задача не такая простая, как изначально предполагалось. Вам нужно будет создать шаблон для идентификации начала записи ([2/5/15 14: 55: 18: 025 UTC] 0000003a JDBCException O), я бы проверил, если DateTime String, а затем HEX номер и JDBCException могут быть безопасным выбором, и если все строки, начинающиеся с пробелов, продолжают одну и ту же запись (это потребует тестирования).

Возможно, вы должны только захватить каждую запись и отправить их для обработки другим событием или даже отправить каждую запись, подлежащую обработке в дочернем процессе, используя для этого что-то вроде POE::Wheel::Run, предположив, что вам необходимо иметь как лексический синтаксический анализатор (log taillor) и семантический парсер (интерпретация записей журнала).

Я не знаю многострочного filter, но вам, вероятно, будет полезно прочитать код POE::Filter::RecordBlock.