opendirとglobとFile::Find::Rule

| 0 Comments | 0 TrackBacks | このエントリーをはてなブックマークに追加 このエントリーのはてなブックマーク件数

ログファイルを処理したいとかで、とあるディレクトリのファイル一覧がほしいときってありますよね!そんなときのための三題話。

opendir

入門書には必ず載ってるopendir。使い方は簡単。ディレクトリ名を入れて開くだけ。あとはopenと同じように開いたハンドルを読み出していくだけ!

opendir(DIR, $dname);
while (defined($fname = readdir(DIR))) {
    print "$fname\n";
}
closedir(DIR);

実行したら、'.' (現在のディレクトリ)とか '..' (ひとつ上のディレクトリ)とかも入ってくるけど、単純に一覧がほしいときは簡単だね!

glob

opendirだととってくるファイル名は何も決められなかったけど、globを使ったら指定できるようになるよ!

たとえば、'accesslog*'ってのに当てはまるものだけがほしいときは

@fnames = glob("$dname/accesslog*");

とやれば配列に入ってくるよ。正規表現チックだけどシェルで'ls'とかやるときの表現なので注意が必要だね。でも、単純だけど便利だよね!

globの中にはスペース区切りでいくつでも指定できるし、シェルで機能する"*.{bz2,gz}"とかも使えるけど、マッチ指定のない文字列を入れたらそれもかえってくるので注意が必要だよ!

% perl -e 'my @temp = glob("*.{bz2,gz} x"); print join("\n", @temp) . "\n";'
wordpress-2.2.1.tar.gz
wp-2.3.2.tar.gz
wp-2.5.1.tar.gz
x
% ls x
ls: x: No such file or directory

File::Find::Rule

最後にモジュールを使ってみるよ!これまでより無駄に高機能だし、OSによってディレクトリの区切りが違う(Winは'\'、Unixは'/'、Macは':'とか)のを気にせず使えるよ!

use File::Find::Rule;
my $rule =  File::Find::Rule->new;
$rule->file; # ファイルであるものを指定
$rule->name( '*.pm' ); # *.pmにマッチするもののみ
my @files = $rule->in( @INC );

これだけで、*.pmってファイルだけが配列でかえってくるよ!

条件を追加するときは'$rule->xxxx'の行を増やしていくだけだよ。たいていのファイルテスト演算子は->readableとかであるし、サイズ指定(->size())もあるし、->maxdepth()とか->mindepth()とかでディレクトリの深さも指定できるよ! File::Find::Ruleのオブジェクトをand/orできるから、複雑な条件でも対応できるよ!

my $rule = File::Find::Rule
$rule->any(
    File::Find::Rule->name('*.pm'), 
    File::Find::Rule->size('<10k'),
    File::Find::Rule->maxdepth(5)
);

・・・・・でも、だいぶ遅い。普通のときは、無名関数とか関数へのリファレンスが必要だけどFile::Findを使えばいいと思うよ!こっちは標準モジュールだしね!(ファイル数が多いと遅いけど。。。)

もっとも、この系統のモジュール、File::Finderとかいろいろあるけど、何が一番いいんだろう。

No TrackBacks

TrackBack URL: http://perl-mongers.org/MT/mt-tb.cgi/24

Leave a comment

About this Entry

This page contains a single entry by himorin published on May 27, 2008 2:49 AM.

TYPO - スペルミス was the previous entry in this blog.

WebService::SimpleでYahoo!の「かな漢字変換Webサービス」を使ってみる is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages

Creative Commons License
This blog is licensed under a Creative Commons License.
Powered by Movable Type 4.21-en