Maneira fácil de analisar o formato de data do syslog

2

Eu gostaria de escrever um script que analise o syslog da última semana.

Mas meu syslog registra em um formato de data idiota, por exemplo "22 de maio". Se fosse registrado em 2013-05-22, essa tarefa seria trivial.

Existe alguma maneira de usar o awk / bash / perl / sed para que eu possa facilmente "grep" os logs de todas as linhas entre dois datetimes?

    
por artfulrobot 22.05.2013 / 13:00

3 respostas

4

Isso é um pouco rotativo demais para o meu gosto, mas pode ser interessante para você:

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)[a-z]*\s+/$month_number{lc $1}-/i'
/var/log/syslog

Isso imprimirá (para stdout) as linhas de registro com a data no formato MM-DD (sem zerar preenchimento para números de mês), o que parece ser uma análise confortável. Isso lida com os nomes dos meses dados em nomes completos e por mês, dados em forma de três letras, independentemente do caso.

EDITAR

Se você deseja zerar preenchimento para números de mês, basta substituir ++$i por sprintf "%02d",++$i

EDIT 2 Dois erros corrigidos graças aos comentários de l0b0 abaixo:

  • Adicionado "pode" à lista de meses
  • Alterou a receita do preenchimento zero para sprintf "%02d", ++$i
por 22.05.2013 / 14:12
2

Veja como eu fiz isso em Perl, embora eu prefira algumas das outras respostas!

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;
    
por 22.05.2013 / 14:17
2

Isso seria OK?

Toda data de espera de linha > 10 e < Dia 18:

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

incluindo o nome do mês:

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

Meses do período, 27 de abril a 4 de maio:

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

Atualização:

Uma variante esboçada usando o getline:

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

Usando script:

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

}
' file

Uso do interruptor:

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

Usando array:

... oh see you have gotten your answer ;)
    
por 22.05.2013 / 13:45