指定ディレクトリ配下にあるファイルを再帰を使わずにリストアップする関数です。
proc find {{pattern "*"} {dir ""}} {
set depth -1
set retry -1
while {$retry} {
set wildcards [lrepeat [incr depth] *]
lappend found {*}[glob -nocomplain -directory $dir -type f -join {*}$wildcards $pattern]
set retry [llength [glob -nocomplain -directory $dir -type d -join {*}$wildcards *]]
}
return $found
}
dirを省略するとカレントディレクトリを起点に検索を始めます。
patternを省略すると全てのファイルをリストアップします。
patternには*.tcl
のようなglobパターンを指定できます。Windowsで試したら大文字と小文字は区別されませんでした。Linuxでは試していませんが、たぶん大文字と小文字は区別されると思います。
再帰を使わず実現できているカラクリはglobコマンドの-joinオプションです。globコマンドのヘルプには
-join
The remaining pattern arguments, after option processing, are treated as a single pattern obtained by joining the arguments with directory separators.
と書かれています。
どういう事かというと、-join * * * *.tcl
と書くと*/*/*.tcl
というパターンでファイルを検索するという意味になり、同じ深さの異なるディレクトリそれぞれでファイル検索を行うことになります。
この機能を利用して、
-
-type f
オプションでファイルをリストアップ -
-type d
オプションでディレクトリが見つかったら-join
に与える*
を増やして1に戻り、ディレクトリが無かったら終了
というループを回しているだけです。
Tclって、ちょくちょくこういう強引・・・もとい、強力な機能が地雷のようにシレッと用意してあったりして、そういうところも魅力のひとつだと思います。