サブディレクトリ内にある全てのファイルを抽出する方法

CGIテクニック集トップへ





概要

サブディレクトリ内を再帰的(recursive)に検索し、全てのファイルを抽出します。どれだけ深いディレクトリでも自動的に探ってファイルを探します。画像一覧3で使用されています。

必用な処理

  1. ルートディレクトリを設定する
  2. ディレクトリ内のファイルを配列に挿入
  3. 配列内からディレクトリであれば、その中から更にファイルのリストを作成し、サブディレクトリがなくなるまで同じことを繰り返す
  4. 配列の内容を表示

サンプルコード

 my $root = ".";
 
 my $filelist = &get_files($root);
 
 foreach (@$filelist){
    print "$_\n";
 }
 
 sub get_files {
    my $dir = shift;
    my $filelist = shift;
    opendir (DIR, "$dir");
    my @list = grep /^[^\.]/, readdir DIR;
    closedir DIR;
    foreach my $file (@list) {
        if (-d "$dir/$file"){
            $filelist = &get_files("$dir/$file", $filelist);
        } else {
            push @$filelist, "$dir/$file";
        }
    }
    return $filelist;
 }

コードの解説

 my $root = ".";

ルートディレクトリを設定します。この場所にあるファイルとそれ以下のサブディレクトリ全てを検索します。

 my $filelist = &get_files($root);

サブルーチンを起動します。引数としてルートディレクトリを渡します。返り値は検出されたファイルが入ったリストのリファレンスになります。リファレンスを使わずにグローバル変数でリストを使用すると、変数の引渡しが省略できるのでコーディングが楽ではあります。その場合は、サブルーチン内でみつかったファイルをリストにpushしていけばいいだけで、返り値も引数も必要なくなります。スクリプトの規模が小さくてスクリプト全体での変数を管理できるのであればそちらでもかまいませんが、色々な場所で再利用したいのであれば、サブルーチンで変数が閉じられるようリファレンスを利用した方が楽です。

 foreach (@$filelist){
    print "$_\n";
 }

リストを画面に表示します。実行はここで終わりになります。

 sub get_files {

サブルーチンの内容です。

    my $dir = shift;

検索するディレクトリを受け取ります。

    my $filelist = shift;

途中結果の検出されたファイルのリストのリファレンスを受け取ります。これに新たに検出されたファイルをどんどん追加していきます。最初の一回は、get_filesの引数が一つだけなので、この内容は空から始まります。

    opendir (DIR, "$dir");

検索するディレクトリをオープンします。

    my @list = grep /^[^\.]/, readdir DIR;

ディレクトリ内の内容をリストに入れます。ここではドットで始まるファイルは除外します。

    closedir DIR;

ディレクトリを閉じます。

    foreach my $file (@list) {

そのディレクトリ内の物を一つ一つチェックしてディレクトリかファイルかをみてそれに従って処理を変えます。

        if (-d "$dir/$file"){
            $filelist = &get_files("$dir/$file", $filelist);

ディレクトリ内の物がディレクトリであれば、そのディレクトリをルートディレクトリとして、今まで記録したファイルのリストを第二引数として自分自身のサブルーチンに渡します。つまり、ディレクトリが見つかった時点でその中に潜り、その中のファイルとディレクトリの検索を始めます。現在のディレクトリの検索は途中で中断され、処理が戻ってきてから再開されます。

        } else {
            push @$filelist, "$dir/$file";

ディレクトリ内の物がファイルであればリストにpushします。リストはリファレンスで後に返り値になります。

        }
    }
    return $filelist;

リストのリファレンスを返します。

 }

サブルーチンの終わり。

関連するCGIテクニック

ディレクトリ(フォルダ)内のファイルの一覧表示
ファイルのリストをアルファベット順でソート