tarファイルを直接 Perlで処理
そのエラー情報ファイルは、Webアプリケーションでエラーが発生する度に1ファイル作成されるものなので、あっという間に膨大な量になってしまいます。放置するとディスクを圧迫するので、普段は毎週 tar + gzipでアーカイブしているのですが、今回の解析のために全部展開すると、少なめに見積もって数十万、下手すると百万以上のファイルが復元されてしまうことになりそうです...
行いたい処理自体は特定パターンを含む場合に、そのファイルに記述されている情報をパターンマッチで抽出して1行出力するという Perlの十八番パターンで、特にファイル自体を復元する必要はないため、なんとか直接Perlで tarファイルを処理する方法を探ってみることにします...
困ったときの Google頼みなのですが、検索キーワードがうまく設定できないのか、世の中にそんなことをしようと思う人がいないのか、それらしいページは引っ掛かりません。orz
うーむ。困りました...
※ 実はこのエントリーを書くためにもう一度調べたら、Archive::Tarというモジュールがあるようです。でも、やっぱり今回したいことには微妙にあっていない感じ...orz
・・・tarファイルは、UNIX黎明期からある由緒ある形式なので情報はあるはずですし、今回処理する tarファイルは、深い階層のディレクトリもデバイスファイルもシンボリックリンクすらないシンプルなものなので、自力で作成してもそんなに手間はかからないはずです...
Solarisの tarの manページを良く見ると、 See Alsoに archives(4)というのがあります。参照する、と Cの構造体の定義の形式で tarのヘッダー部分のマッピング定義が書かれています。
あ!これだ。ということで、早速 Perlスクリプトで読むべく unpackのパラメタに落としていきます...
予想通り形式はいたってシンプルで、これなら楽勝かと思ったのですが、一箇所問題がありました。ファイルサイズとしてヘッダに格納されている文字列と実際の値が異なっているのです。たぶん、なにかのルールがあるはずなのですが、今ひとつ正解が見つかりません... orz
困っていろいろな tarファイルをダンプして見比べているとサイズが 64バイトのファイルに 100が設定されているのを見つけました。
で、わかりました。 -- 8進数 orz
そういえば、古い UNIX文化は 8進数の方がお好みでした。そうでした。
まぁともかく、カラクリがわかれば簡単です。時間もないので、簡単に作ります...
tarの中身は特定のフォーマットを持つテキストファイルで、それを連続で処理できれば良いので、ヘッダを読んだら識別用のパターンをつけてファイル名を出力し、後はサイズ分内容を読んでひたすら出力するようにし、実際の解析処理は別スクリプトにしてパイプで繋ぐことにします...
gzip展開のために、前処理で gzcatをしてもそこそこの時間で処理できるようです。ふぅ
# スクリプトは追記に書いています....
#!/usr/bin/perl
while (read(STDIN, $header, 512)) {
($name,$mode,$uid,$gid,$size,$mtime,$chksum,
$typeflag,$linkname,$magic,$version,$uname,$gname,
$devmajor,$devminor,$prefix) =
unpack("A100A8A8A8A12A12A1A100A6A2A32A32A8A8A155", $header);
next unless $name;
$sz = oct($size);
print "*** ", $name,"\n";
while ($sz > 0) {
read(STDIN, $buff, 512);
if ($sz > 512) {
print $buff;
$sz -= 512;
} else {
print substr($buff, 0, $sz);
$sz = 0;
}
}
}
「SYSTEM開発・運用」の新着
- ユニコードが全然ユニじゃない件 [ 2006年12月 5日]
- スパムメールと闘う・職場編 [ 2006年4月24日]
- DNSサーバが DDoSの発射台にされる問題について [ 2006年3月30日]
- Sendmailに深刻な脆弱性 [ 2006年3月23日]
- tarファイルを直接 Perlで処理 [ 2006年3月14日]
- 続・Sun Studio11を試してみる [ 2006年2月15日]
- Sun Studio11を試してみる [ 2006年2月14日]
- gcc3.4.2と Oracle InstantClient [ 2006年2月10日]
トラックバック(0)
このブログ記事を参照しているブログ一覧: tarファイルを直接 Perlで処理
このブログ記事に対するトラックバックURL: http://morishoji.homelinux.net/mt/mt-tb.cgi/35




コメントする