I have a directory that contains another directory named ABC_<version number>

I'd like to set my path to whatever ABC_<version number> happens to be (in a modulefile)

How do I use glob in TCL to get the name of the directory I want and put it into a TCL variable?

Thanks!

1

2 Answers

The glob command expands wildcards, but produces a Tcl list of everything that matches, so you need to be a bit careful. What's more, the order of the list is “random” — it depends on the raw order of entries in the OS's directory structure, which isn't easily predicted in general — so you really need to decide what you want. Also, if you only want a single item of the list, you must use lindex (or lassign in a degenerate operation mode) to pick it out: otherwise your code will blow up when it encounters a user who puts special characters (space, or one of a small list of other ones) in a pathname. It pays to be safe from the beginning.

For example, if you want to only match a single element and error out otherwise, you should do this:

set thePaths [glob -directory $theDir -type d ABC_*] if {[llength $thePaths] != 1} { error "ambiguous match for ABC_* in $theDir" } set theDir [lindex $thePaths 0] 

If instead you want to sort by the version number and pick the (presumably) newes, you can use lsort -dictionary. That's pretty magical internally (seriously; read the docs if you want to see what it really does), but does the right thing with all sane version number schemes.

set thePaths [glob -directory $theDir -type d ABC_*] set theSortedPaths [lsort -dictionary -decreasing $thePaths] set theDir [lindex $theSortedPaths 0] 

You could theoretically make a custom sort by the actual date on the directories, but that's more complex and can sometimes surprise when you're doing system maintenance.

Notice the use of -type d in glob. That's a type filter, which is great in this case where you're explicitly only wanting to get directory names back. The other main useful option there (in general) is -type f to get only real files.

Turns out the answer was:

 set abc_path [glob -directory $env(RELDIR) ABC_*] 

No need for quotes around the path. The -directory controls where you look.

Later in the modulefile

 append-path PATH $abc_path 
1

ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobG1wZ2WEeoSOrJytZZFiw6K%2ByJqZpZ1dqbxurYyfoKWdnpa6pnnUrKCnn12cubCu