jima 2014-01-27
I paste here the proc (GetFilePaths) I have to generate listings of files (following possibly a pattern) and folders given some starting folder.
This proc uses another auxiliary one (MakeRelative) in the cases full paths are not needed but relative ones.
I reckon the names given to possible options and their possible values are perhaps unfortunate because of the hyphens.
# Proc GetFilePaths. # Arguments. # filePath The starting file path to operate on. # -expected An option list with expected results. # Possible value -expectedFiles. # Possible value -expectedFolders. # Defaults to {-expectedFiles -expectedFolders}. # pattern Pattern to use only for files. # Defaults to *. # -makeRelative An option to tail the fPaths. # Possible value -makeRelativeYes. # Possible value -makeRelativeNo. # Defaults to -makeRelativeNo. # -recursive An internal flag to signal that is a recursive call. # It is mostly used internally. # Defaults to "" when invoked by the user. # Internally it allows to pass the initial filePath. # The user can pass -recursiveNo to avoid recursion. # # Returns. # The list of files and folders suitable for ordered file deleting. # If -makeRelativeYes then: # Files and folders of the list are relative to filePath. proc GetFilePaths { filePath {-expected {-expectedFiles -expectedFolders}} {pattern *} {-makeRelative -makeRelativeNo} {-recursive ""} } { # Prepare the list for this invokation. set result "" # Deal with each folder at filePath level. # Only if recurse is allowed. if {${-recursive} ne "-recursiveNo"} { foreach folder [glob -nocomplain -type d -dir $filePath *] { # Recurse. if {${-recursive} eq ""} { lappend result {*}[GetFilePaths \ $folder ${-expected} $pattern ${-makeRelative} $filePath ] } else { lappend result {*}[GetFilePaths \ $folder ${-expected} $pattern ${-makeRelative} ${-recursive} ] } # If files are needed, process each folder to get them. if {"-expectedFiles" in ${-expected}} { foreach file [glob -nocomplain -type f -dir $folder $pattern] { # Make relative if needed. if {${-makeRelative} eq "-makeRelativeYes"} { lappend result [ MakeRelative $filePath $file ${-recursive} ] } else { lappend result $file } } } # If folders are needed, append them to the result list. # This is done after files are added. # To provide results in an order that suits rm command. if {"-expectedFolders" in ${-expected}} { # Make relative if needed. if {${-makeRelative} eq "-makeRelativeYes"} { lappend result [ MakeRelative $filePath $folder ${-recursive} ] } else { lappend result $folder } } };# Each folder. };# Folders at filePath level if not -recurseNo. # Do not forget to process files at top level if they are needed. if { ( (${-recursive} eq "") || (${-recursive} eq "-recursiveNo") ) && ("-expectedFiles" in ${-expected}) } { foreach file [glob -nocomplain -type f -dir $filePath $pattern] { # Make relative if needed. if {${-makeRelative} eq "-makeRelativeYes"} { lappend result [MakeRelative $filePath $file ${-recursive}] } else { lappend result $file } } } # Do not forget to process folders at top level if they are needed. if { (${-recursive} eq "-recursiveNo") && ("-expectedFolders" in ${-expected}) } { foreach file [glob -nocomplain -type d -dir $filePath $pattern] { # Make relative if needed. if {${-makeRelative} eq "-makeRelativeYes"} { lappend result [MakeRelative $filePath $file ${-recursive}] } else { lappend result $file } } } # Return the list with results. return $result }; # Proc GetFilePaths. # Proc MakeRelative. # When calling this externally do not set -recursive argument. proc MakeRelative {filePath file {-recursive ""}} { set result {} if {${-recursive} eq "" || ${-recursive} eq "-recursiveNo"} { set prefix $filePath } else { set prefix ${-recursive} } set first [string first $prefix/ $file] if {$first == -1} { set result $file } else { set result [string range $file [string length $prefix/] end] } return $result };# Proc MakeRelative.
Some examples:
Get all files and folders that hang from a given folder.
set filesAndFolders [GetFilePaths $folder]
Get all files (but not folders) that hang from localFolder and follow the pattern *.IN.
set inFiles [GetFilePaths $localFolder -expectedFiles *.IN]