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: