Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1481439
  • 博文数量: 463
  • 博客积分: 10540
  • 博客等级: 上将
  • 技术积分: 5450
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-12 08:30
文章分类

全部博文(463)

文章存档

2014年(2)

2012年(14)

2011年(42)

2010年(18)

2009年(78)

2008年(35)

2007年(182)

2006年(92)

我的朋友

分类:

2010-01-15 15:30:50

#!/usr/bin/perl
use strict;
use Getopt::Std;
use vars qw($opt_d $opt_s $opt_e $opt_k $opt_g %date_format @filename $keyword $regular);

sub Usage
{
    print "Usage: parselog <[<-d Time_format> <-s Start_time> <-e End_time>] [-g gapcharacter] [-k keyword]> [filename]\n";
    print <        -d  Specified time format
            %H: hour (00 .. 23)
            %I: Hour (01 .. 12)
            %k: hour (0 .. 23)
            %l: hour (1 .. 12)
            %M: minute (00 .. 59)
            %n: min (0 .. 59)
            %S: s (00 .. 60)
            %s: seconds (0 .. 60)
            %p: Display the local AM or PM
            %a: day of the week (Sun.. Sat)
            %A: day of the week (Sunday.. Saturday)
            %b: the month (Jan.. Dec)
            %B: the month (January.. December)
            %w: the first days of the week (0 .. 6)
            %d: Day (01 .. 31)
            %D: Day (1 .. 31)
            %m: month (01 .. 12)
            %L: month (1 .. 12)
            %y: the last two digits of the year (00.99)
            %Y: Full Year (0000 .. 9999)
           
        -s  Start Time
        -e  END Time
        -g  The interval between the specified keyword strings, does not support the regular
        -k  Analysis matched the specified keywords, keyword included in the single quotation
            marks, a number of keywords separated by inter-default with -=- can also be
            customized, and to sequence matching, keyword does not support the regular
        filename Specify the log file to be analyzed, which can specify multiple files
                 (separated by spaces), if there is no file to read from the pipe.
        Script default output for the screen, with no parameters or parameter error output help information.
EOF
    exit -1;
}
sub Reg #过滤正则
{
    my $key = shift @_;
    $key =~ s/\./\\\./g;
    $key =~ s/\*/\\\*/g;
    $key =~ s/\^/\\\^/g;
    $key =~ s/\?/\\\?/g;
    $key =~ s/\$/\\\$/g;
    $key =~ s/\|/\\\|/g;
    $key =~ s/\]/\\\]/g;
    $key =~ s/\[/\\\[/g;   
    $key =~ s/\\d/\\\\d/g;
    $key =~ s/\\D/\\\\D/g;
    $key =~ s/\\w/\\\\w/g;
    $key =~ s/\\W/\\\\W/g;
    $key =~ s/\\s/\\\\s/g;
    $key =~ s/\\S/\\\\S/g;
    return $key;
}
sub Options #选项参数处理器
{
    getopts('d:s:e:g:k:');
    if (!$opt_k && !$opt_d) {
        Usage;
    } elsif ($opt_d) {
        if (!$opt_s || !$opt_e) {
            Usage;
        }
    }
    if (@ARGV > 0) {
        while (my $tmp = shift @ARGV) {
            push (@filename, $tmp);
        }
    } else {
        push (@filename, 'STDIN');
    }
    my $interval = '';
    $keyword = '';
    $opt_k = '' if (!$opt_k);
    if ($opt_g) {
        $interval = Reg($opt_g);
    } else {
        $interval = '-=-';
    }
    if ($opt_k =~ /$interval/) {
        $keyword = Reg($opt_k);
        $keyword =~ s/$interval/\.\*/g;
    } else {
        $keyword = Reg($opt_k);
    }
}
sub Parse_regular #参数分析
{
    my $format = shift @_;
    my $str;
    $regular = '';
    Usage unless ($format =~ /%/);
    for (my $i = 0; $i < length($format); $i++) {
        my $char = substr($format, $i, 1);
        if ($char ne '%') {
            Reg($char);
            $regular =  $regular . $char;
        } else {
            $i++;
            $char = substr($format, $i, 1);
            $str = $str . $char;
            if (exists $date_format{$char}) {
                $regular =  $regular . $date_format{$char};
            } else {
                Usage;
            }
        }
    }
    return $str;
}
sub Parse_time #提取匹配时间表
{
    my $line = shift @_;
    my $str = shift @_;
    my ($time, $j, $tmp, %dtime); #$j regular value
    $j = 1;
    if ($line =~ m/$regular/i) {
        for (my $i = 0; $i < length($str); $i++) {
            my $char = substr($str, $i, 1);
            $tmp = eval "\$" . $j;
            $dtime{$char} = $tmp;
            $j++;
        }
        ($time = $dtime{'Y'}) if (exists $dtime{'Y'});
        ($time = $dtime{'y'}) if (exists $dtime{'y'});
       
        ($time = $time . $dtime{'m'}) if (exists $dtime{'m'});
        ($time = $time . $dtime{'L'}) if (exists $dtime{'L'});
       
        if (exists $dtime{'b'}) {
            ($time = $time . '1') if (lc($dtime{'b'}) eq 'jan');
            ($time = $time . '2') if (lc($dtime{'b'}) eq 'feb');
            ($time = $time . '3') if (lc($dtime{'b'}) eq 'mar');
            ($time = $time . '4') if (lc($dtime{'b'}) eq 'apr');
            ($time = $time . '5') if (lc($dtime{'b'}) eq 'may');
            ($time = $time . '6') if (lc($dtime{'b'}) eq 'jun');
            ($time = $time . '7') if (lc($dtime{'b'}) eq 'jul');
            ($time = $time . '8') if (lc($dtime{'b'}) eq 'aug');
            ($time = $time . '9') if (lc($dtime{'b'}) eq 'sept');
            ($time = $time . '9') if (lc($dtime{'b'}) eq 'sep');
            ($time = $time . '10') if (lc($dtime{'b'}) eq 'oct');
            ($time = $time . '11') if (lc($dtime{'b'}) eq 'nov');
            ($time = $time . '12') if (lc($dtime{'b'}) eq 'dec');
        }
       
        if (exists $dtime{'B'}) {
            ($time = $time . '1') if (lc($dtime{'B'}) eq 'january');
            ($time = $time . '2') if (lc($dtime{'B'}) eq 'february');
            ($time = $time . '3') if (lc($dtime{'B'}) eq 'march');
            ($time = $time . '4') if (lc($dtime{'B'}) eq 'april');
            ($time = $time . '5') if (lc($dtime{'B'}) eq 'may');
            ($time = $time . '6') if (lc($dtime{'B'}) eq 'june');
            ($time = $time . '7') if (lc($dtime{'B'}) eq 'july');
            ($time = $time . '8') if (lc($dtime{'B'}) eq 'august');
            ($time = $time . '9') if (lc($dtime{'B'}) eq 'september');
            ($time = $time . '10') if (lc($dtime{'B'}) eq 'october');
            ($time = $time . '11') if (lc($dtime{'B'}) eq 'november');
            ($time = $time . '12') if (lc($dtime{'B'}) eq 'december');
        }
       
        ($time = $time . $dtime{'d'}) if (exists $dtime{'d'});
        ($time = $time . $dtime{'D'}) if (exists $dtime{'D'});
       
        if (exists $dtime{'a'}) {
            ($time = $time . '1') if (lc($dtime{'a'}) eq 'mon');
            ($time = $time . '2') if (lc($dtime{'a'}) eq 'tues');
            ($time = $time . '2') if (lc($dtime{'a'}) eq 'tue');
            ($time = $time . '3') if (lc($dtime{'a'}) eq 'wed');
            ($time = $time . '4') if (lc($dtime{'a'}) eq 'thurs');
            ($time = $time . '5') if (lc($dtime{'a'}) eq 'fri');
            ($time = $time . '6') if (lc($dtime{'a'}) eq 'sat');
            ($time = $time . '6') if (lc($dtime{'a'}) eq 'st');
            ($time = $time . '7') if (lc($dtime{'a'}) eq 'sun');
        }
       
        if (exists $dtime{'A'}) {
            ($time = $time . '1') if (lc($dtime{'A'}) eq 'monday');
            ($time = $time . '2') if (lc($dtime{'A'}) eq 'tuesday');
            ($time = $time . '3') if (lc($dtime{'A'}) eq 'wednesday');
            ($time = $time . '3') if (lc($dtime{'A'}) eq 'midweek');
            ($time = $time . '4') if (lc($dtime{'A'}) eq 'thursday');
            ($time = $time . '5') if (lc($dtime{'A'}) eq 'friday');
            ($time = $time . '6') if (lc($dtime{'A'}) eq 'saturday');
            ($time = $time . '7') if (lc($dtime{'A'}) eq 'sunday');
        }
       
        if (exists $dtime{'w'}) {
            if ($dtime{'w'} == 0) {
                $time = $time . '7';
            } else {
                $time = $time . $dtime{'w'};
            }
        }
       
        if (exists $dtime{'p'}) {
            ($time = $time . '1') if ($dtime{'p'} =~ /AM|am/);
            ($time = $time . '2') if ($dtime{'p'} =~ /PM|pm/);
        }
       
        ($time = $time . $dtime{'H'}) if (exists $dtime{'H'});
        ($time = $time . $dtime{'I'}) if (exists $dtime{'I'});
        ($time = $time . $dtime{'k'}) if (exists $dtime{'k'});
        ($time = $time . $dtime{'l'}) if (exists $dtime{'l'});
       
        ($time = $time . $dtime{'M'}) if (exists $dtime{'M'});
        ($time = $time . $dtime{'n'}) if (exists $dtime{'n'});
       
        ($time = $time . $dtime{'S'}) if (exists $dtime{'S'});
        ($time = $time . $dtime{'s'}) if (exists $dtime{'s'});
        $time = $time + 1 - 1;
        return $time;
    } else {
        return -1;
    }   

}
#[main]
%date_format = ('Y' => '(\d{4})',
                'y' => '(\d{2})',
                'm' => '([0-1]{1}\d{1})',
                'L' => '(\d{1,2})',
                'd' => '(\d{2})',
                'D' => '(\d{1,2})',
                'H' => '([0-2]{1}\d{1})',
                'M' => '(\d{2})',
                'n' => '(\d{2})',
                'S' => '(\d{2})',
                's' => '(\d{1,2})',
                'I' => '([0-1]{1}\d{1})',
                'k' => '(\d{1,2})',
                'l' => '(\d{1,2})',
                'p' => '(am|pm)',
                'w' => '(\d{1})',
                'a' => '(Mon|Tues|tue|Wed|Thurs|Fri|Sat|St|Sun)',
                'A' => '(Monday|Tuesday|Wednesday|midweek|Thursday|Friday|Saturday|Sunday)',
                'b' => '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sept|sep|Oct|Nov|Dec)',
                'B' => '(January|February|March|April|may|June|July|August|September|october|november|december)'
                );
my ($string, $start_time, $end_time, $line_time);
Options;
if ($opt_d || $opt_k) {
    if ($opt_d) {
        $string = Parse_regular($opt_d);
        $start_time = Parse_time($opt_s, $string);
        $end_time = Parse_time($opt_e, $string);
        Usage if (($start_time == -1) || ($end_time == -1));
    }
    my $handle;  #文件描述符
    my $multi_line = 0; #多行标识
    my $key_flag = 0; #关键字匹配标识
    my @multiline;
    for(my $k = 0; $k < @filename; $k++) {
        my $file = shift @filename;
        if ($file ne 'STDIN') {
            unless (-r $file) {
                print "Read $file failed!\n";
                exit -2;
            }
            open (F, "$file") || die "open $file error!";
            $handle = 'F';
        } else {
            $handle = 'STDIN'; #从管道读取
        }
       
        while (my $lines = <$handle>) {
            if ($opt_k && !$opt_d) {
                print "$lines" if ($lines =~ /$keyword/i);
                next;
            }
           
            if ($opt_d && !$opt_k) {
                $line_time = Parse_time($lines, $string);
                next if (($multi_line == 0) && ($line_time < $start_time));
                last if ($line_time > $end_time);
                if ($line_time >= $start_time && $line_time <= $end_time) {
                    print "$lines";
                    $multi_line = 1;
                } else {
                    print "$lines";
                }
            }
           
            if ($opt_d && $opt_k) { #时间+关键字=多行匹配
                $line_time = Parse_time($lines, $string);
               
                next if (($line_time == -1) && ($multi_line == 0));
                next if (($line_time != -1) && ($line_time < $start_time));
                last if (($line_time > $end_time) && ($key_flag == 0));
                if (($line_time == -1) && ($multi_line == 1)) {
                    if ($lines =~ /$keyword/i) {
                        push (@multiline, $lines);
                        $key_flag = 1;
                    } else {
                        push (@multiline, $lines);
                    }
                    next;
                }
                $multi_line++;
                if ($multi_line > 1) {
                    if ($key_flag == 1) {
                        while (my $buff = shift @multiline) {
                            print $buff;
                        }
                    }   
                    $multi_line = 1;
                    $key_flag = 0;
                }
                @multiline = ();
                push (@multiline, $lines);
               
                if ($lines =~ /$keyword/i) { #时间+关键字=单行匹配
                    next if (($line_time != -1) && ($line_time < $start_time));
                    last if ($line_time > $end_time);
                    if ($line_time >= $start_time && $line_time <= $end_time) {
                        print "$lines";
                    }
                }
            }
        }
        close($handle);
        print "\n\n\n[$file]\n\n\n" if (@filename > 1);
    }
} else {
    Usage;
}

阅读(1347) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-01-15 16:07:15

用perl写的日志分析脚本 笔记! perlcc -B parselog.pl