以前の記事「Mac OS XにWebalizerをインストール → DNSCacheでハマる」ではMac OS XにてWebalizerをインストールする方法を書いた。このとき日本語化するオプション(--with-language=japanese
)をつけたのだが、これによって用語が日本語化される代わりに、Total Search Strings(検索文字列リスト)が文字化けしてしまう。
原因は、検索文字列のエンコーディングにUTF-8が使用されているのに引き替え、HTML自体にはEUC-JPが使われているためだ。しょうがないので、作成したHTMLファイルに細工を加えることにする。
話が前後するが、Webalizerの起動にはcronによる自動実行を使っている。プロンプトからcrontab -e
と打ち込んで次の行を書いた。
0 */4 * * * /bin/sh /var/root/webalizer.sh
これによって6時間ごとにwebalizer.sh
というスクリプトが実行される。その中身はこうだ1。
#!/bin/sh cat /var/log/apache2/access_log | perl -ne '/^(localhost|127\.0\.0\.1|::1|192\.168\.)/ or print' > /tmp/access_log webalizer -c /opt/local/etc/webalizer/root.conf perl -MEncode -i -pe '/Total Search Strings/ .. m!</TABLE>! and /NOWRAP/ and Encode::from_to( $_, utf8 => "eucjp" )' /Library/WebServer/usage/usage*.html
順に説明する。ここでは2つのことを行っている。
- LAN内からのアクセスを解析結果から除く
- 検索文字列リストの文字化けを解消する
1番は2行目で実現している。Perlのワンライナーを使って行頭に次の4つの文字列を含む行以外を/tmp/access_log
というファイルにコピーする。
- localhost
- 127.0.0.1
- ::1
- 192.168.
3行目でWebalizerを実行し解析結果のファイルを生成。そして4行目が肝。今回のテーマである文字コード変換だ。
perl -MEncode -i -pe '/Total Search Strings/ .. m!</TABLE>! and /NOWRAP/ and Encode::from_to( $_, utf8 => "eucjp" )' /Library/WebServer/usage/usage*.html
これだけでは何のことやらわからないので、スクリプトに直してみよう。
#!/usr/bin/perl use Encode; while (<>) { if ( /Total Search Strings/ .. m!</TABLE>! ) { if ( /NOWRAP/ ) { Encode::from_to( $_, "utf8", "eucjp" ); } } print; }
ここでは「【perl】範囲演算子についての日本語マニュアルの誤訳」に書いた範囲演算子(フリップフロップ演算子)を使っている。上のコードで4行目のif
文は「『Total Seach Strings』を含む文と『</TABLE>』を含む文の間なら」と言う意味になる。その範囲内で、『NOWRAP』という文字列を含む文の文字コードをUTF-8からEUC-JPに変換している(6行目)というわけだ。
後はPerlワンライナーの基本、-p
オプションと-i
オプションを付け加えて完成だ。これで、Webalizerによって生成されたHTMLファイルのうち、必要な部分だけを文字コード変換できた。
Perlの起動オプションと、範囲演算子の説明を改めて貼っておく。
Perl第4回:PerlTips(コマンドラインオプション)
http://www.stackasterisk.jp/tech/program/perl04_04.jsp【perl】範囲演算子についての日本語マニュアルの誤訳
https://blog.delphinus.dev/2010/02/range-operator.htmlO’Reilly Japan – プログラミングPerl 第3版 VOLUME 1
120頁 3.15 範囲演算子
Google ブックスで該当頁を開く
-
実物とは少し変えてある。例えば、「
perl
」は「/opt/local/bin/perl
」などとフルパスで書いているが、煩雑なので省略した。(それでもかなり見にくいねorz) ↩