[ Team LiB ] Previous Section Next Section

Matching File Names with glob

The glob command expands a pattern into the set of matching file names. The general form of the glob command is:

glob ?options? pattern ?pattern? ...

The pattern syntax is similar to the string match patterns:

  • * matches zero or more characters.

  • ? matches a single character.

  • [abc] matches a set of characters.

  • {a,b,c} matches any of a, b, or c.

  • All other characters must match themselves.

Table 9-8 lists the options for the glob command.

Table 9-8. glob command options

-directory dir

Search for files in the directory dir. (Tcl 8.3)

-join

The remaining pattern arguments are treated as a single pattern obtained by joining them with directory separators. (Tcl 8.3)

-nocomplain

Causes glob to return an empty list if no files match. Otherwise an error is raised.

-path path

Search for files in the given path prefix path. Allows you to search in areas that may contain glob-sensitive characters. (Tcl 8.3)

-tails

Only return the part of each file found that follows the last directory named in the -directory or -path argument. (Tcl 8.4)

-types types

Only return files matching the types specified.

--

Signifies the end of flags. Must be used if pattern begins with a -.

Unlike the glob matching in csh, the Tcl glob command matches only the names of existing files. In csh, the {a,b} construct can match nonexistent names. In addition, the results of glob are not sorted. Use the lsort command to sort its result if you find it important.

Example 9-11 shows the FindFile procedure, which traverses the file system hierarchy using recursion. At each iteration it saves its current directory and then attempts to change to the next subdirectory. A catch guards against bogus names. The glob command matches file names:

Example 9-11 Finding a file by name
proc FindFile { startDir namePat } {
   set pwd [pwd]
   if {[catch {cd $startDir} err]} {
      puts stderr $err
      return
   }
   foreach match [glob -nocomplain -- $namePat] {
      puts stdout [file join $startDir $match]
   }
   foreach file {[glob -nocomplain *]} {
      if [file isdirectory $file] {
         FindFile [file join $startDir $file] $namePat
      }
   }
   cd $pwd
}

The -types option allows for special filtered matching similar to the UNIX find command. The first form is like the -type option of find: b (block special file), c (character special file), d (directory), f (plain file), l (symbolic link), p (named pipe), or s (socket), where multiple types may be specified in the list. Glob will return all files which match at least one of the types given.

The second form specifies types where all the types given must match. These are r (readable), w (writable) and x (executable) as file permissions, and readonly and hidden as special cases. On the Macintosh, MacOS types and creators are also supported, where any item which is four characters long is assumed to be a MacOS type (e.g. TEXT). Items which are of the form {macintosh type XXXX} or {macintosh creator XXXX} will match types or creators respectively. Unrecognized types, or specifications of multiple MacOS types/creators will signal an error.

The two forms may be mixed, so -types {d f r w} will find all regular files OR directories that have both read AND write permissions.

Expanding Tilde in File Names

The glob command also expands a leading tilde (~) in filenames. There are two cases:

  • ~/ expands to the current user's home directory.

  • ~user expands to the home directory of user.

If you have a file that starts with a literal tilde, you can avoid the tilde expansion by adding a leading ./ (e.g., ./~foobar).

    [ Team LiB ] Previous Section Next Section