Легкий способ разбора формата даты syslog

Я бы хотел написать сценарий, анализирующий syslog прошлой недели.

Но мой журнал syslog регистрируется в формате глупой даты, например «22 мая». Если он будет зарегистрирован как 2013-05-22, эта задача будет тривиальной.

Есть ли способ использования awk / bash / perl / sed, который я могу легко «grep» журналов для всех строк между двумя датами?

  • выскочить писать в syslog простым способом
  • Извлечь файл из полностью отключенной машины, возможно, через сообщения ядра
  • Где находится буфер кольцевого ядра относительно rsyslog?
  • MacOS: история USB (имя и временная метка подключенных устройств)
  • Как перенаправить Tomcat журналы обратно в catalina.out вместо syslog?
  • Является ли systemd-journald реализацией syslog?
  • используйте другой сокет, чем / dev / log, общесистемный
  • как показать цвета в syslog
  • 3 Solutions collect form web for “Легкий способ разбора формата даты syslog”

    Это слишком круто для моего вкуса, но это может вас заинтересовать:

     perl -p -e ' BEGIN{ @months=qw(jan feb mar apr may jun jul aug sep oct nov dec); $month_number{$_}=++$i for @months; $months_regex= join "|",@months; } s/^\s*($months_regex)[az]*\s+/$month_number{lc $1}-/i' /var/log/syslog 

    Это будет печатать (для stdout) строки журнала с датой в формате MM-DD (без нулевого заполнения для номеров месяцев), который вам кажется удобным для синтаксического разбора. Это обрабатывает месячные имена, указанные в полном виде, и имена месяцев, указанные в трехбуквенной форме, независимо от случая.


    РЕДАКТИРОВАТЬ

    Если вы хотите нулевое заполнение для чисел месяца, просто замените ++$i на sprintf "%02d",++$i

    EDIT 2 Две ошибки исправлены благодаря комментариям l0b0 ниже:

    • Добавлен «май» в список месяцев
    • Изменен рецепт нулевого заполнения для sprintf "%02d", ++$i

    Вот как я это сделал в Perl, хотя я предпочитаю некоторые другие ответы!

     use DateTime::Format::Strptime; my $parser = DateTime::Format::Strptime->new( pattern => '%B %d %Y'); m/^(\w+ \d+)/; print $parser->parse_datetime("$1 " . DateTime->now->year)->ymd; 

    Все будет в порядке?

    Каждая дата проведения линии> 10 и <18:

     awk '$2 > 10 && $2 < 18 {print}' file 

    В том числе имя месяца:

     awk '$1 == "May" && $2 > 10 && $2 < 18 {print}' file 

    Промежуточные месяцы, с 27 апреля по 4 мая:

     awk '($1 == "Apr" && $2 > 26) || ($1 == "May" && $2 < 5){print}' file 

    Обновить:

    Эскизный вариант с использованием getline:

     awk '"date '+%m%d' -d " $1$2 | getline date; close("date"); \ date > 426 && date < 505 {print}' file 

    Использование скрипта:

     awk -v from=520 -v to=523 ' { d = ((match("JanFebMarAprMayJunJulAugSepOctNovDec", $1) + 2) / 3 )$2; if (d >= from && d <= to) print; } ' file 

    Использование переключателя:

     awk -v from=520 -v to=523 ' function date2time() { switch ($1) { case "Jan": return 1$2; break; case "Feb": return 2$2; break; case "Mar": return 3$2; break; case "Apr": return 4$2; break; case "May": return 5$2; break; case "Jun": return 6$2; break; case "Jul": return 7$2; break; case "Aug": return 8$2; break; case "Sep": return 9$2; break; case "Oct": return 10$2; break; case "Nov": return 11$2; break; case "Dec": return 12$2; break; } } { d = date2time(); if (d >= from && d <= to) print; } ' file 

    Использование массива:

     ... oh see you have gotten your answer ;) 
    Linux и Unix - лучшая ОС в мире.