Set a variable to a filename using glob

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

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like