4

古い回答を使用して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

たくさんのファイルを取得しますが、それらはすべて現在のディレクトリにあります。

目標は、マシン上のすべてのサブフォルダー内のすべてのファイルとそのパスを取得することです。助けてくれる人はいますか?

私が本当にやりたいのは、*。cファイルの数が最も多いディレクトリを見つけることです。ただし、すべてのファイルとそのパスを一覧表示できれば、各ディレクトリにあるファイルの数を数えて、数が最も多いファイルを取得できます。

4

3 に答える 3

4

古いバージョンのTclを使用しています。[file normalize]2002年頃にTcl8.4で導入されました。すでにアップグレードしています。

できない場合は、globを使用しますが、ファイルに対して1回だけ呼び出してから、ディレクトリをウォークします。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]
于 2012-06-19T19:20:56.883 に答える
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"
}
于 2012-06-19T19:30:52.233 に答える
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 ]
于 2012-10-12T03:55:35.137 に答える