tarファイルを直接 Perlで処理

カテゴリ: SYSTEM開発・運用
| | コメント(0) | トラックバック(0)
仕事で書いたプログラムに不具合があって(6年前からの潜在不良なんだけど ^^;;;)、影響調査のために、半年分のエラー情報を解析するハメになってしまいました。orz

そのエラー情報ファイルは、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開発・運用」の新着

トラックバック(0)

このブログ記事を参照しているブログ一覧: tarファイルを直接 Perlで処理

このブログ記事に対するトラックバックURL: http://morishoji.homelinux.net/mt/mt-tb.cgi/35

コメントする

最近のコメント


最近のコメントを表示...
Powered by Movable Type 4.01