まさはる's Weblog

まさはる's Weblog
Macintoshとオーディオの話題

2004年7月 5日

Perlを使ってみました(その2)

Category : Terminal / Posted at 2004年7月 5日 23:16

 前回、「リンク元が同じものを1行にまとめるプログラム」というものを作ってみたのですが、一体どんな意味があるのかと思い考えてみたところ、あまり意味がないことに気づきました*1...(^_^;
 そこで、refererをチェックするのではなく、requestをチェックして、「1アクセスを1行にまとめるプログラム」に改良しました。

#!/usr/bin/perl -w
use strict;
# ログファイルの整理プログラム log.pl [-dhqDHQ] ver.1.1
# オプション d:date, h:host, q:request を整形して出力
#            D:date, H:host, Q:request を整形せずに出力
 
# 入力するログファイルのフォーマット
# host ident authuser date "request" status bytes "referer"
# "user-agent"\n
# date = [day/month/year:hour:minute:second zone]
# day 2桁, month 3文字, year 4桁, hour 2桁, minute 2桁, second 2桁
# zone (+|-)4桁
# request = command file-pass-name HTTP/*.*
 
# 出力するログファイルの標準フォーマット(-dhq)
# date host request
# date = day/month/year:hour:minute:second
# day 2桁, month 3文字, year 4桁, hour 2桁, minute 2桁, second 2桁 計20桁
# host 後半20文字
# request 前半37文字
 
my @delete = qw/ .jpg .gif .cgi .css .ico .sit .txt /; # 除外する拡張子名
my $option = '-dhq';
if (@ARGV) {
    if ($ARGV[0] =~ /^-[dhqDHQ]/) {
        $option = shift @ARGV;
    }
}
 
foreach (<STDIN>) {
    /(^\S+).+(\[\S+ \S+\]) "([^"]+)".+"[^"]+" "[^"]+"\n/;
    my $host = $1;
    my $date = $2;
    my $request = $3;
 
    # 除外する拡張子を持つファイルをリクエストしている行は出力しない
    my $out = 1;                                # 初期値 = 出力する
    foreach (@delete) {
        if ($request =~ /$_/) {
            $out = 0;                           # 出力しない
            last;
        }
    }
 
    # 出力
    if ($out == 1) {
        if ($option =~ /d/) {                   # 秒まで
            print substr($date, 1, 20), ' ';
        } elsif ($option =~ /D/) {              # そのまま
            print "$date ";
        }
        if ($option =~ /h/) {                   # 後半20文字
            printf "%20.20s ", substr($host, -20, 20);
        } elsif ($option =~ /H/) {              # そのまま
            print "$host ";
        }
        if ($option =~ /q/) {                   # 前半37文字
            $request =~ /^\S+ (\S+) \S+/;
            print substr($1, 0, 37);
        } elsif ($option =~ /Q/) {              # そのまま
            print "\"", $request, "\"";
        }
        print "\n";
    }
}

 ただでさえPerlっぽい部分が少ないのに、さらに少なくなってしまいました。なお、@deleteに除外する拡張子名(例えば.xmlとか.rdf等)を半角スペースで区切って追加すると、それらのファイルを要求している行が出力されなくなります。

実行結果
前回と微妙に違いますな...w
*1 削除しようかと思いましたが、Perlで作った初めてのプログラムなので、記念に曝しておきます...(^_^;
このページのトップに戻る