2

I'd like to write a script that analyses the last week's syslog.

But my syslog logs in a stupid date format, e.g. "May 22". If it logged as 2013-05-22, this task would be trivial.

Is there a way using awk / bash / perl / sed that I can easily 'grep' the logs for all lines between two datetimes?

  • what version of syslog are we talking about? Most daemons will let you configure the date format using some kind of directive. You don't have to accept the defaults. It's set up that way by default because some log parsers/analyzers break if you change the date format. – Bratchley May 22 '13 at 11:39
  • for example in rsyslog and syslog-ng, you specify the date format in the template you've selected to be default. – Bratchley May 22 '13 at 11:43
  • @JoelDavis "some log parsers.. break" exactly why I daredn't change it! Thanks for the tip, will check the man pages for whatever I'm using... – artfulrobot May 22 '13 at 11:50
  • I'm using syslogd - can't find how to set date format! – artfulrobot May 22 '13 at 11:56
  • syslogd is a bit ambiguous (some syslog variations share that name for their main executable). Is this Mac OS X's syslogd? – Bratchley May 22 '13 at 12:00
4

This is a bit too roundabout for my taste, but it may be of interest to you:

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

This will print (to stdout) the log lines with the date in MM-DD format (without zero padding for month numbers) which you seem to be comfortable parsing. This handles month names given in full and month names given in 3-letter form, irrespective of case.


EDIT

If you want zero padding for month numbers, simply replace ++$i with sprintf "%02d",++$i

EDIT 2 Two mistakes fixed thanks to l0b0's comments below:

  • Added 'may' to the months list
  • Changed the recipe for zero padding to sprintf "%02d", ++$i
2

Here's how I did it in Perl, although I prefer some of the other answers!

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;
  • 1
    One-liner replacing the date: sudo perl -n -e '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, " ", $2, "\n");' /var/log/syslog – l0b0 May 23 '13 at 12:49
  • @l0b0 Handy :-P – artfulrobot May 24 '13 at 12:56
2

Would this be OK?

Every line holding date > 10th and < 18th:

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

Including month name:

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

Span months, April 27th to May 4th:

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

Update:

A sketchy variant using getline:

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

Using script:

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

}
' file

Using switch:

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

Using array:

... oh see you have gotten your answer ;)
  • 1
    what about periods which span months? – artfulrobot May 22 '13 at 11:49
  • Thanks, but it's still difficult to generalise this for a given span. Would have to choose one of 2nd or 3rd forms based on whether the month was different. – artfulrobot May 22 '13 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.