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

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

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

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

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 ;) 
  • Вызывает ли процесс, вызывающий убийцу-убийцу?
  • rsyslog не отбрасывает сообщение, как следует
  • После установки ubuntu install + software raid 0 мы видим: отказ от ввода-вывода в автономном устройстве
  • / var / log / syslog опустели
  • Отдельное имя хоста сервера, отображаемое в журналах cron этого сервера
  • Что вызывает исключения ata в моем syslog и как их решить
  • Почему abrt использует данные журнала для процесса, который не сработал?
  • Настройка syslogd в Ubuntu
  • Объединение файлов журналов с разными форматами временных меток
  • Команда Logger - как хранить журналы в заданном файле?
  • Для чего относится байтовая последовательность в этом сообщении kerneloops (syslogd @ hostname)?
  • Linux и Unix - лучшая ОС в мире.