11

他のフォルダーと後続のサブディレクトリにある他のtcl procを大量にソースするメインのTCL procがあります。たとえば、メイン プロシージャには次のように記述されています。

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

フォルダAとフォルダBのすべてをソースすることを常に知っているときに、そのようにするのはちょっとばかげているようです。フォルダー全体のすべての .tcl ファイルをソースするだけの機能 (または簡単な方法) はありますか?

4

7 に答える 7

6

おそらく、プラットフォームに依存せず、プロセスにパイプする代わりに組み込みコマンドを使用します。

foreach script [glob [file join $basepath folderA *.tcl]] {
  source $script
}

folderBに対して繰り返します。

より厳しい選択基準があり、他のプラットフォームでの実行について心配する必要がない場合は、findを使用する方が柔軟な場合があります。

于 2009-01-10T07:41:22.107 に答える
2

以前の回答に基づいて、このバージョンはシンボリックリンクによって作成されたサイクルを処理し、その過程でシンボリックリンクによる重複ファイルも排除します。

# findFiles
# basedir - the directory to start looking in
# pattern - A pattern, as defined by the glob command, that the files must match
proc findFiles {directory 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 directory [string trimright [file join [file normalize $directory] { }]]

    # Starting with the passed in directory, do a breadth first search for
    # subdirectories. Avoid cycles by normalizing all file paths and checking
    # for duplicates at each level.

    set directories [list]
    set parents $directory
    while {[llength $parents] > 0} {

        # Find all the children at the current level
        set children [list]
        foreach parent $parents {
            set children [concat $children [glob -nocomplain -type {d r} -path $parent *]]
        }

        # Normalize the children
        set length [llength $children]
        for {set i 0} {$i < $length} {incr i} {
            lset children $i [string trimright [file join [file normalize [lindex $children $i]] { }]]
        }

        # Make the list of children unique
        set children [lsort -unique $children]

        # Find the children that are not duplicates, use them for the next level
        set parents [list]
        foreach child $children {
            if {[lsearch -sorted $directories $child] == -1} {
                lappend parents $child
            }
        }

        # Append the next level directories to the complete list
        set directories [lsort -unique [concat $directories $parents]]
    }

    # Get all the files in the passed in directory and all its subdirectories
    set result [list]
    foreach directory $directories {
        set result [concat $result [glob -nocomplain -type {f r} -path $directory -- $pattern]]
    }

    # Normalize the filenames
    set length [llength $result]
    for {set i 0} {$i < $length} {incr i} {
        lset result $i [file normalize [lindex $result $i]]
    }

    # Return only unique filenames
    return [lsort -unique $result]
}
于 2009-01-15T21:43:33.043 に答える
2

シュレンクと同じ考え:

package require Tclx
for_recursive_glob scriptName $basepath *.tcl {
    source $scriptName
}

$ basepathの下にある他のフォルダーではなくfolderAとfolderBのみが必要な場合:

package require Tclx
for_recursive_glob scriptName [list $basepath/folderA $basepath/folderB] *.tcl {
    source $scriptName
}
于 2009-09-14T17:48:25.277 に答える
2

1 つの方法を次に示します。

set includes [open "|find $basedir -name \*.tcl -print" r]

while { [gets $includes include] >= 0 } {
  source $include
}

close $includes
于 2009-01-09T20:01:19.633 に答える
0

ジョセフ・ブイの答えは、最初のフォルダー内のファイルをスキップすることを除いてうまくいきます。

変化する:

ディレクトリの設定 [リスト]
に:
ディレクトリの設定 [list $directory]

修正する

于 2016-01-24T08:36:24.380 に答える