mkdir() はフォルダ(ディレクトリ)を作成します。0755 の部分には作成するフォルダの パーミッション を指定します。パーミッションを省略すると、0777 に umask() の値でマスクをかけたもので作成されます。成功すると真を、失敗すると偽を返し、$! にエラーメッセージを設定します。
if (mkdir("data", 0755)) { print "成功しました。\n"; } else { print "失敗しました。($!)\n"; }
/tmp/aaa フォルダが存在していない場合、mkdir() では /tmp/aaa/bbb の作成に失敗してしまいますが、File::Path パッケージに含まれる mkpath() は、必要とされる階層のフォルダをまとめて作成することができます。第2引数に 0 以外の値を指定すると、フォルダが作成される度に mkdir /tmp/aaa のようなメッセージが表示されます。第3引数には パーミッション を指定してください。
use File::Path; eval { mkpath("/tmp/aaa/bbb", 0, 0755); }; if ($@) { print "$@"; }
mkpath(["/tmp/aaa/bbb", "/tmp/aaa/ccc"], 0, 0) のようにして、複数のフォルダを指定することもできます。作成に失敗するとスクリプトが異常終了してしまうので、eval() を用いてエラーをトラップしてやるとよいようです。
rmdir() はフォルダを削除します。成功すると真を、失敗すると偽を返し、$! にエラーメッセージを設定します。
if (rmdir("data")) { print "成功しました。\n"; } else { print "失敗しました。($!)\n"; }
アクセス権が無かったり、フォルダの中にファイルが残っていると、rmdir() は失敗します。
File::Path パッケージに含まれる rmtree() は、指定したフォルダ配下のすべてのファイルやフォルダを削除します。第2引数に 0 以外の値を指定すると、フォルダが作成される度に rmdir /tmp/aaa/bbb のようなメッセージが表示されます。第3引数に 1 を指定すると安全モードとなり、書き込み不可になっているファイルやフォルダの削除が抑止されます。
use File::Path; if (rmtree("/tmp/aaa", 0, 0)) { print "成功しました。\n"; } else { print "失敗しました。\n"; }
rmtree(["aaa", "bbb"], 0, 0) のようにして、複数のフォルダを指定することもできます。削除に成功したフォルダの個数を返します。
getcwd() は、現在の 作業フォルダ(カレントディレクトリ、カレントフォルダ)を得ます。
require "getcwd.pl"; $dir = getcwd(); print "dir = $dir\n";
Windows などで、getpwd.pl がうまく動作しない場合は、Cwd モジュールを利用する方法もあります。
use Cwd; $dir = Cwd::getcwd(); print "dir = $dir\n";
chdir() は、現在のプロセスの作業フォルダ(カレントフォルダ、カレントディレクトリ)を移動します。引数を省略すると環境変数 HOME で指定されたフォルダにジャンプします。作業フォルダは現在のプロセス、およびそのプロセスから起動された子プロセスで有効です。成功すると真を、失敗すると偽を返します。
use Cwd; print Cwd::getcwd() . "\n"; # 現在のカレントフォルダを表示 if (chdir("/Temp")) { print "成功しました。\n"; } else { print "失敗しました。($!)\n"; } print Cwd::getcwd() . "\n"; # 移動後のカレントフォルダを表示
chroot() は、現在のプロセスのルートフォルダ(トップフォルダ)を変更します。例えば /home/tanaka/ に chroot した場合、以後、/home/tanaka/file.txt は /file.txt としてアクセスすることになります。
use Cwd; if (chroot("/home/tanaka/")) { print "成功しました。\n"; } else { print "失敗しました。($!)\n"; }
ルートフォルダの変更は、子プロセスにも引き継がれます。/home/tanaka の下にあるファイルしか参照できなくなるため、CGI のセキュリティを強化する際にも役立ちます。Windows ではサポートされていません。
<*> は、現在のフォルダにあるファイルやフォルダの一覧を配列として返します。* の代わりに *.txt とすると、*.txt にマッチするファイルの一覧が返されます。
while ($file = <*>) { print "$file\n"; }
glob() は、指定したファイル名にマッチするファイルの一覧をリストで返します。Perl 5 から利用可能です。
while ($file = glob("*.txt")) { print "$file\n"; }
ファイル名のマッチングに用いられる書式を下記に示します。
例 | 説明 | 例にマッチするファイル |
---|---|---|
xx*.txt | アスタリスク(*)は0文字以上の任意文字にマッチします。 | xx.txt, xxx.txt, xxaa.txt など |
xx???.txt | クエスチョン(?)は1文字の任意文字にマッチします。 | xxabc.txt, xxxyz.txt, xx123.txt など |
[abc].txt | [abc] は a または b または c にマッチします。 | a.txt, b.txt, c.txt |
[a-c].txt | [a-c] は a~c のいずれかの文字にマッチします。 | a.txt, b.txt, c.txt |
{aa,bb}.txt | {aa,bb} は aa または bb にマッチします。 | aa.txt, bb.txt |
opendir()、readdir()、closedir() は指定したフォルダを開き、ファイルやフォルダの一覧を読み取り、クローズします。"." は現在の作業フォルダを意味しています。返される一覧の中には、自フォルダを示す "." や、ひとつ上のフォルダを示す ".." も含まれるので、下記のようにして "." や ".." を無視するようにするとよいでしょう。
opendir(DIR, ".") || die "失敗"; # フォルダをオープンする while ($file = readdir(DIR)) { # ファイル名をひとつずつ読み出す if (($file eq ".") || ($file eq "..")) { next; # . と .. を無視する } print "$file\n"; } closedir(DIR); # フォルダを閉じる
telldir() は、ファイル一覧読み込み中の現在の位置を返します。この値を seekdir() に渡してやることにより、読み込み位置をリワインドすることができます。Perl 5 では、読み込み位置を先頭に戻す rewinddir() を使用することもできます。
opendir(DIR, "."); $pos = telldir(DIR); seekdir(DIR, $pos); rewinddir(DIR); closedir(DIR);
サブルーチンが自分自身を直接的に(または間接的に)呼び出すことを 再起呼び出し と呼びます。例では再起呼び出しのテクニックを用いて、指定したフォルダ配下にあるすべてのファイルに対して処理(DoFile)を行います。
FindFile("/Windows"); # フォルダ配下のすべてのファイルを表示する sub FindFile { local($dir) = @_; local(*DIR, $file); # 引数で指定されたフォルダ直下のフォルダやファイルについて・・・ if (!opendir(DIR, $dir)) { return; } while ($file = readdir(DIR)) { if (($file eq ".") || ($file eq "..")) { # "." や ".." は無視する next; } if (-d "$dir/$file") { # フォルダなら FindFile() を再帰的に呼び出す FindFile("$dir/$file"); } else { # フォルダ以外なら処理ルーチン DoFile() を呼び出す DoFile("$dir/$file"); } } closedir(DIR); } # ファイル処理(例として単にファイル名を表示) sub DoFile { local($file) = @_; print "$file\n"; }
File::Find モジュールを用いても、FindFile() と同様のことが可能です。第1引数には処理関数へのリファレンスを、第2引数には探索の対象となるフォルダを指定します。
use File::Find; find(\&DoFile, "/perl"); sub DoFile { print "$File::Find::name\n"; }
処理関数には、$File::Find::dir でファイルが存在するパス名が、$_ でファイル名が、$File::Find::name でファイルのフルパス名が渡されます。詳細は perldoc File::Find を実行して表示されるドキュメントを参照してください。
FindBin モジュールを用いることにより、スクリプトファイルが置かれているフォルダの絶対パスを求めることができます。また、特殊変数 $0 は、スクリプトファイル名を示します。両者を組み合わせることにより、現在実行中のスクリプトのフルパス名を求めることができます。
use FindBin qw($Dir); $file = $0; $file =~ s/^.*[\/\\]//; print "$Dir/$file\n";
実行例は以下のようになります。
C:/PerlTest/folder10.pl