**Information about Files - file, glob** !!!!!! '''[Tcl Tutorial Lesson 24%|%Previous lesson%|%]''' | '''[Tcl Tutorial Index%|%Index%|%]''' | '''[Tcl Tutorial Lesson 26%|%Next lesson%|%]''' !!!!!! There are two commands that provide information about the file system, `glob` and `file`. They provide a method to examine and manipulate the files and directories that is virtually indepedent of the operating system. Some subcommands and pieces of information are, however, necessarily system-dependent, as they refer to features of a particular operating system. `glob` returns the names of files and subdirectories in a directory. It uses a name matching mechanism similar to the UNIX `ls` command or the Windows (DOS) `dir` command, to return a list of names that match a pattern. `file` provides three sets of functionality: * String manipulation appropriate to parsing file names %|Subcommand |Purpose|% |`dirname` |Returns directory portion of path | |`extension` |Returns file name extension | |`join` |Join directories and the file name to one string | |`nativename` |Returns the ''native'' name of the file/directory| |`rootname` |Returns file name without extension | |`split` |Split the string into directory and file names | |`tail` |Returns filename without directory | * Information about an entry in a directory: %|Subcommand |Purpose|% |`atime` |Returns time of last access | |`executable` |Returns 1 if file is executable by the user | |`exists` |Returns 1 if file exists, 0 otherwise | |`isdirectory`|Returns 1 if entry is a directory, 0 otherwise | |`isfile` |Returns 1 if entry is a regular file, 0 if not | |`lstat` |Returns array of file status information | |`mtime` |Returns time of last data modification | |`owned` |Returns 1 if file is owned by the user | |`readable` |Returns 1 if file is readable by the user | |`readlink` |Returns name of file pointed to by a symbolic link| |`size` |Returns file size in bytes | |`stat` |Returns array of file status information | |`type` |Returns type of file | |`writable` |Returns 1 if file is writeable by the user | * Manipulating the files and directories themselves: %|Subcommand |Purpose|% |`copy` |Copy a file or a directory | |`delete` |Delete a file or a directory | |`mkdir` |Create a new directory | |`rename` |Rename or move a file or directory | Between these two commands, a program can obtain most of the information that it needs and can manipulate the files and directories. While retrieving information about what files are present and what properties they have is usually a highly platform-dependent matter, Tcl provides an interface that hides almost all details that are specific to the platform (but are irrelevant to the programmer). To take advantage of this feature, always manipulate file names via the `file join` and `file split` commands and the others in the first category. For instance to refer to a file in a directory upwards of the current one: ====== set upfile [file join ".." "myfile.out"] # upfile will have the value "../myfile.out" ====== (The ".." indicates the "parent directory") Because external commands may not always deal gracefully with the uniform representation that Tcl employs (with forward slashes as directory separators), Tcl also provides a command to turn the string into one that is native to the platform: ====== # # On Windows the name becomes "..\myfile.out" # set newname [file nativename [file join ".." "myfile.out"]] ====== Retrieving all the files with extension ".tcl" in the current directory: ====== set tclfiles [glob *.tcl] puts "Name - date of last modification" foreach f $tclfiles { puts "$f - [clock format [file mtime $f] -format %x]" } ====== (The clock command turns the number of seconds returned by the `file mtime` command into a simple date string, like "07/01/2017") `glob ?switches? pattern ?pattern2 ...?`: Returns a list of file names that match `pattern` or `pattern2`, ... The `switches` may be one of the following (there are more switches available): * `-nocomplain` allows `glob` to return an empty list without causing an error. Without this flag, an error would be generated when the empty list was returned. * `-types typeList` selects which type of files/directory the command should return. The `typeList` may consist of type letters, like a "d" for directories and "f" for ordinary files as well as letters and keywords indicating the user's permissions ("r" for files/directories that can be read for instance). * `--` marks the end of switches. This allows the use of "-" in a pattern without confusing the glob parser. The `pattern` follows the same matching rules as the string match globbing rules with these exceptions: * `{a,b,...}` Matches any of the strings a,b, etc. * A "." at the beginning of a filename must match a "." in the filename. The "." is only a wildcard if it is not the first character in a name. * All "/" must match exactly. * If the first two characters in `pattern` are `~/`, then the `~` is replaced by the value of the `HOME` environment variable. * If the first character in `pattern` is a`~`, followed by a login id, then the `~loginid` is replaced by the path of loginid's home directory. Note that the filenames that match `pattern` are returned in an arbitrary order (that is, do not expect them to be sorted in alphabetical order, for instance). `file atime name`: Returns the number of seconds since some system-dependent start date, also known as the "epoch" (frequently 1/1/1970) when the file `name` was last accessed. Generates an error if the file doesn't exist, or the access time cannot be queried. `file copy ?-force? name target`: Copy the file/directory `name` to a new file `target` (or to an existing directory with that name). The switch `-force` allows you to overwrite existing files. `file delete ?-force? name`: Delete the file/directory `name`. The switch `-force` allows you to delete non-empty directories. `file dirname name`: Returns the directory portion of a path/filename string. If `name` contains no slashes, `file dirname` returns a ".". `file executable name`: Returns 1 if file `name` is executable by the current user, otherwise returns 0. `file exists name`: Returns 1 if the file `name` exists, and the user has search access in all the directories leading to the file. Otherwise, 0 is returned. `file extension name`: Returns the file extension. `file isdirectory name`: Returns 1 if file name is a directory, otherwise returns 0. `file isfile name`: Returns 1 if file name is a regular file, otherwise returns 0. `file lstat name varName`: This returns the same information returned by the system call `lstat`. The results are placed in the associative array `varName`. The indexes in `varName` are: * `atime` - time of last access * `ctime` - time of last file status change * `dev` - inode's device * `gid` - group ID of the file's group * `ino` - inode's number * `mode` - inode protection mode * `mtime` - time of last data modification * `nlink` - number of hard links * `size` - file size, in bytes * `type` - type of file * `uid` - user ID of the file's owner Note: Because this calls `lstat`, if `name` is a symbolic link,the values in `varName` will refer to the link, not the file that is linked to.(See also the `stat` subcommand) `file mkdir name`: Create a new directory `name`. `file mtime name`: Returns the time of the last modification in seconds since Jan 1, 1970 or whatever start date (also known as epoch) the system uses. `file owned name`: Returns 1 if the file is owned by the current user, otherwise returns 0. `file readable name`: Returns 1 if the file is readable by the current user, otherwise returns 0. `file readlink name`: Returns the name of the file a symlink is pointing to. If `name` isn't a symlink, or can't be read, an error is generated. `file rename `?-force? name target`: Rename file/directory `name` to the new name `target` (or to an existing directory with that name). The switch `-force` allows you to overwrite existing files. `file rootname name`: Returns all the characters in `name` up to but not including the last ".". Returns the name if `name` doesn't include a ".". `file size name`: Returns the size of `name` in bytes. `file stat name varName`: This returns the same information returned by the system call `stat`. The results are placed in the associative array `varName`. The indexes in `varName` are: * `atime` - time of last access * `ctime` - time of last file status change * `dev` - inode's device * `gid` - group ID of the file's group * `ino` - inode's number * `mode` - inode protection mode * `mtime` - time of last data modification * `nlink` - number of hard links * `size` - file size in bytes * `type` - type of file * `uid` - user ID of the file's owner `file tail name`: Returns all of the characters in `name` after the last slash. Returns the name if `name` contains no slashes. `file type name`: Returns a string giving the type of file name, which will be one of: * `file` - normal file * `directory` - directory * `characterSpecial` - character oriented device * `blockSpecial` - block oriented device * `fifo` - named pipe * `link` - symbolic link * `socket` - named socket `file writable name`: Returns 1 if file name is writable by the current user, otherwise returns 0. ''Note:'' The overview given above does not cover all the details of the various subcommands, nor does it list all subcommands. Please check the man pages for these. ---- ***Example*** ====== # # Report all the files and subdirectories in the current directory # For files: show the size # For directories: show that they _are_ directories # set dirs [glob -nocomplain -type d *] if { [llength $dirs] > 0 } { puts "Directories:" foreach d [lsort $dirs] { puts " $d" } } else { puts "(no subdirectories)" } set files [glob -nocomplain -type f *] if { [llength $files] > 0 } { puts "Files:" foreach f [lsort $files] { puts " [file size $f] - $f (extension: [file extension $f])" } } else { puts "(no files)" } ====== <> Resulting output The output of the above example for an arbitrary directory: ======none Directories: CVS figs html latex pdf Files: 36 - .cvsignore (extension: .cvsignore) 4 - .tex2page.hdir (extension: .hdir) 461 - Makefile (extension: ) 509 - README.txt (extension: .txt) 2708 - refs.bib (extension: .bib) ====== !!!!!! '''[Tcl Tutorial Lesson 24%|%Previous lesson%|%]''' | '''[Tcl Tutorial Index%|%Index%|%]''' | '''[Tcl Tutorial Lesson 26%|%Next lesson%|%]''' !!!!!!