ディレクトリ ウォーカーを書きたいときはいつでも、常に標準のFile::Findモジュールを使用してください。ファイルシステムを扱うときは、奇妙なコーナーケースを処理できる必要がありますが、単純な実装ではほとんど処理できません。
コールバックに提供される環境(wanted
ドキュメントで名前が付けられています) には、実行したいことに特に役立つ 3 つの変数があります。
$File::Find::dir
現在のディレクトリ名です
$_
そのディレクトリ内の現在のファイル名です
$File::Find::name
ファイルへの完全なパス名です
.
またはではないディレクトリを見つけたら..
、完全なパスを記録し、その親を削除します。これは、リーフ ディレクトリではないことがわかっています。find
File::Findでは深さ優先検索が実行されるため、最後に記録されたパスは葉でなければなりません。
#! /usr/bin/env perl
use strict;
use warnings;
use File::Find;
@ARGV = (".") unless @ARGV;
my %dirs;
sub wanted {
return unless -d && !/^\.\.?\z/;
++$dirs{$File::Find::name};
delete $dirs{$File::Find::dir};
}
find \&wanted, @ARGV;
print "$_\n" for sort keys %dirs;
現在のディレクトリのサブディレクトリに対して実行できます
$リーフディレクトリ時間
時間/aa/bb/何か
時間/aa/bc/何でも
時間/aa/bc/すべて
時間/ab/cc/こちら
時間/ab/cc/そこ
時間/ab/cd/どこでも
またはフルパスを使用する
$リーフディレクトリ/tmp/時間
/tmp/time/aa/bb/何か
/tmp/time/aa/bc/なんでも
/tmp/time/aa/bc/すべて
/tmp/time/ab/cc/こちら
/tmp/time/ab/cc/そこ
/tmp/time/ab/cd/どこでも
または、同じ呼び出しで複数のディレクトリを plumb します。
$ mkdir -p /tmp/foo/bar/baz/quux
$ リーフディレクトリ /tmp/time /tmp/foo
/tmp/foo/bar/baz/quux
/tmp/time/aa/bb/何か
/tmp/time/aa/bc/なんでも
/tmp/time/aa/bc/すべて
/tmp/time/ab/cc/こちら
/tmp/time/ab/cc/そこ
/tmp/time/ab/cd/どこでも