TCL:递归搜索子目录以获取所有.tcl文件

Lyn*_*don 10 tcl

我有一个主要的TCL过程,在其他文件夹和后续子目录中获取大量其他tcl过程.例如,在主程序中,它具有:

source $basepath/folderA/1A.tcl
source $basepath/folderA/2A.tcl
source $basepath/folderA/3A.tcl
source $basepath/folderB/1B.tcl
source $basepath/folderB/2B.tcl
source $basepath/folderB/3B.tcl
Run Code Online (Sandbox Code Playgroud)

当我总是知道我将在folderA和folderB中获取所有内容时,这样做似乎有点愚蠢.是否有一个函数(或简单的方法)允许我只是在整个文件夹中获取所有.tcl文件?

Jac*_*son 10

在ramanman的回复基础上,继承了一个例程,该例程使用内置的TCL文件命令解决问题,并以递归方式沿着目录树工作.

# findFiles
# basedir - the directory to start looking in
# pattern - A pattern, as defined by the glob command, that the files must match
proc findFiles { basedir pattern } {

    # Fix the directory name, this ensures the directory name is in the
    # native format for the platform and contains a final directory seperator
    set basedir [string trimright [file join [file normalize $basedir] { }]]
    set fileList {}

    # Look in the current directory for matching files, -type {f r}
    # means ony readable normal files are looked at, -nocomplain stops
    # an error being thrown if the returned list is empty
    foreach fileName [glob -nocomplain -type {f r} -path $basedir $pattern] {
        lappend fileList $fileName
    }

    # Now look for any sub direcories in the current directory
    foreach dirName [glob -nocomplain -type {d  r} -path $basedir *] {
        # Recusively call the routine on the sub directory and append any
        # new files to the results
        set subDirList [findFiles $dirName $pattern]
        if { [llength $subDirList] > 0 } {
            foreach subDirFile $subDirList {
                lappend fileList $subDirFile
            }
        }
    }
    return $fileList
 }
Run Code Online (Sandbox Code Playgroud)

  • 如果您有一个创建循环的符号链接,您将得到"太多嵌套评估(无限循环?)"错误. (3认同)

sch*_*enk 10

在船上使用tcllib会变得微不足道:

package require fileutil
foreach file [fileutil::findByPattern $basepath *.tcl] {
    source $file
}
Run Code Online (Sandbox Code Playgroud)


小智 5

也许更多的平台独立并使用内置命令而不是管道进程:

foreach script [glob [file join $basepath folderA *.tcl]] {
  source $script
}
Run Code Online (Sandbox Code Playgroud)

对folderB重复一遍.

如果您有更严格的选择标准,并且不担心在任何其他平台上运行,使用find可能会更灵活.