tcl深度递归文件搜索,搜索扩展名为* .c的文件

时间:2012-06-19 16:05:33

标签: recursion tcl file-search

使用旧答案在tcl中搜索文件: https://stackoverflow.com/a/435094/984975

首先让我们讨论一下我现在在做什么: 使用此功能:(归功于Jacson)

# 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
 }

并调用以下命令:

findFiles some_dir_name *.c

目前的结果:

bad option "normalize": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable

现在,如果我们运行:

glob *.c

我们收到了很多文件,但所有文件都在当前目录中。

目标是在机器上的 ALL 子文件夹中获取 ALL 文件及其路径。 谁可以帮忙?

我真正想要做的是找到具有最高* .c文件数的目录。 但是,如果我可以列出所有文件及其路径,我可以算一下,每个目录中有多少文件,并获得最高数量的文件。

3 个答案:

答案 0 :(得分:4)

我会使用::fileutil::traverse函数来执行此操作。

类似的东西:

package require ::fileutil::traverse

proc check_path {path} {
     string equal [file extension $path] ".c"
}

set obj [::fileutil::traverse %AUTO% -filter check_path]
array set pathes {}
$obj foreach file {
     if {[info exists pathes([file dirname $file])]} {
        incr pathes([file dirname $file])
     } else {
        set pathes([file dirname $file]) 1
     }
}

# print pathes and find the biggest
foreach {name value} [array get pathes] {
     puts "$name : $value"
}

答案 1 :(得分:3)

您使用的是旧版Tcl。 [file normalize]在2002年左右在Tcl 8.4中被引入。已升级。

如果你不能 - 那么你使用glob但只为文件调用一次然后遍历目录。请参阅glob -types选项。

这是一个演示:

proc on_visit {path} {
    puts $path
}

proc visit {base glob func} {
    foreach f [glob -nocomplain -types f -directory $base $glob] {
        if {[catch {eval $func [list [file join $base $f]]} err]} {
            puts stderr "error: $err"
        }
    }
    foreach d [glob -nocomplain -types d -directory $base *] {
        visit [file join $base $d] $glob $func
    }
}

proc main {base} {
    visit $base *.c [list on_visit]
}

main [lindex $argv 0]

答案 2 :(得分:2)

对于快速(1级)文件模式匹配,请使用:

glob **/*.c

如果要递归搜索,请使用:

proc ::findFiles { baseDir pattern } {
  set dirs [ glob -nocomplain -type d [ file join $baseDir * ] ]
  set files {}
  foreach dir $dirs { 
    lappend files {*}[ findFiles $dir $pattern ] 
  }
  lappend files {*}[ glob -nocomplain -type f [ file join $baseDir $pattern ] ] 
  return $files
}

puts [ join [ findFiles $basepath "*.tcl" ] \n ]
相关问题