2015-01-22 3 views
0

У меня есть несколько строк в моем массиве @lines, в котором * показывает мне время начала команды (как синхронизация/Fetch) и линию с тем же ProcessId pid и командой без * показывает мне время окончания , Они могут быть не всегда непрерывными. Я хотел бы получить startdate и enddate конкретных processID и cmd. Как для usera ЦМД sync с ProcessId 11859 началась в 2015/01/13 13:53:01.491-05:00 и закончилась в 2015/01/13 13:55:01.492-05:00

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

my %users; 
foreach my $line (@lines) { 
    if ($line =~ m{(\*)+}) { 
     ($stdate, $sttime, $pid, $user, $cmd) = split ' ', $line; 
     $startdate ="$stdate $sttime"; 
    } 
    else { 
    ($eddate, $edtime, $pid, $user, $cmd) = split ' ', $line; 
    $enddate = "$eddate $edtime"; 
    }   

     $users{$pid} = [ $startdate, $enddate, $user, $cmd ]; 

    } 

Содержание в @lines:

2015/01/13 13:53:01.491-05:00 11859 usera  *sync_cmd 7f1f9bfff700 10.101.17.111  
2015/01/13 13:57:02.079-05:00 11863 userb  *fetch_cmd 7f1f9bfff700 10.101.17.111 
2015/01/13 13:59:02.079-05:00 11863 userb  fetch_cmd 7f1f9bfff700 10.101.17.111 
2015/01/13 13:55:01.492-05:00 11859 usera  sync_cmd 7f1f9bfff700 10.101.17.111 
+0

@chilemagic: Не пустые строки, если в строке 1 есть дата синхронизации 'sync_cmd', конечная дата для того же идентификатора команды и процесса может быть не строка 2, она может быть в любой строке. – Jill448

+1

Не было бы лучше сделать хэш хэшей для этого прецедента? – Sobrique

ответ

2

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

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

Не могли бы вы не вместо сделать:

my %processes; 

foreach (@lines) { 
    my ($date, $time, $pid, $user, $cmd, @everything_else) = split; 

    if ($cmd =~ m/^\*/) { 

     #if command starts with a * - it started. 
     if (defined $processes{$pid}) { 
      print "WARNING: $pid reused\n"; 
     } 

     $processes{$pid}{'start_date'} = $date; 
     $processes{$pid}{'time'}  = $time; 
     $processes{$pid}{'user'}  = $user; 
     $processes{$pid}{'cmd'}  = $cmd; 
    } 
    else { 
     #cmd does not start with '*'. 
     if ($processes{$pid}{'cmd'} =~ m/$cmd/) { 

      #this works, because 'some_command' is a substring of '*some_command'. 
      $processes{$pid}{'end_date'} = $date; 
      $processes{$pid}{'end_time'} = $time; 
     } 
     else { 
      print 
       "WARNING: $pid has a command of $cmd, where it started with $processes{$pid}{'cmd'}\n"; 
     } 
    } 
} 

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

+0

'* cmd' обозначает начало, а следующая строка с такими же' pid' и 'cmd' обозначает конец процесса. – Jill448

1

Когда вы назначаете %users{$pid} вы предполагая, что самый последний $startdate и $enddate являются актуальными. Эта проблема усугубляется тем фактом, что ваши переменные, содержащие ваши значения полей, имеют область больше, чем цикл foreach, позволяя этим значениям истекать кровью между записями.

В блоке if вы должны присвоить значения массиву $startdate, $user, $cmd. Индивидуально или как срез, если хотите. В блоке else вы должны назначить $enddate его элементу в массиве.

Regex extra credit: вам не кажется, что в записи больше *, что делает + в избытке регулярным. В качестве дополнительного бонуса, без него группа захвата также не имеет значения. m{\*} должно быть очень красиво.

+0

Спасибо за ответ, но его все еще не ясно для меня относительно блока 'else'. Как я могу назначить '$ enddate' связанному' pid'? – Jill448

+0

'$ users {$ pid} [1] = $ enddate;' будет моим первым инстинктом. Предполагая, что вы сохраняете свои поля в том же порядке ... – tjd

Смежные вопросы