Home directory expansion
Wildcard characters
Ranges
Alternation
Indefinite directories
Match failures
Caution: the copy, xcopy, rename and del commands
See also
The notion of wildcarding is pretty simple: the user gives just a few characters describing the filename he’s looking for and system fills in the rest. With “vanilla” Windows, wildcarding is the responsibility of each application, based on the command-line arguments it’s given. Typically, the application designer fulfills this by linking in a library routine which does a simple-minded half-hearted wildcarding.
Hamilton C shell does the wildcarding before invoking the application. The shell’s wildcarding includes five components: home directory expansion, wildcarding characters, ranges, alternation and indefinite directories. A powerful recursive match algorithm is employed to guarantee a sensible result no matter how complex the pattern.
The tilde character, ~, is recognized as shorthand for the home directory. In the simplest form, we can use it just by itself:
There’s also shorthand for children or siblings of the home directory:
The wildcard characters, * and ?, provide shorthand for “match any string” and “match any single character,” respectively.
Suppose the home directory contained the following contents:
The following example shows the use of ? to match any single character. Wildcard results are always shown alphabetically in lower case. No distinction is made between directories and files.
The * can match zero or more arbitrary characters except : or \; in contrast to Windows-style wildcarding, * can match .. If there are ordinary characters in the pattern, they must also be matched.
Because the wildcarding is done before the command is invoked (without the command even being aware), wildcarding can even be done on a cd command:
Wildcarding is most emphatically not restricted to matches only against a single directory level. Here’s an example that wildcards across all the subdirectories, looking for .c files that begin with a.
Wildcarding can even be done against driveletters. For example:
When wildcarding against driveletters, the shell restricts the set of drives it will search down to just those specified by the DRIVEMASK environment variable. If you don’t specify a DRIVEMASK, the default is all drives except the floppies a: and b:. The search is restricted so you don’t waste time trying to access slow removable media that may not even be ready.
Ranges describe a set of characters, any one of which will be matched. It’s specified as a list of acceptable characters inside [...] brackets. The range [be] means either b or e; [b-e] is shorthand for any character in the sequence b through e. Within the brackets, any number of hyphenated sequences and single characters can pasted one after the other in any order. For example, [a-cu-zgkmp] is a perfectly legal range. Here are a couple examples. Notice that ranges can also be used with driveletters.
An exclusion range is written as a set of characters inside the brackets that starts with a circumflex. It’ll match any single character not in the range.
Alternation, specified with {...} braces, is a shorthand way of specifying that all the combinations of frontparts and backparts should be generated. There isn’t any requirement that the filenames constructed actually exist.
Alternation can be combined arbitrarily with the other wildcard constructs:
The ellipsis, ..., is an indefinite definite directory wildcard. It’ll match zero or more arbitrary directory levels -- whatever it takes to make the rest of the wildcard match. To be recognized as a wildcard, the context must indicate it’s really a filename, i.e., it must be preceded by \, /, ~ or : or followed by \ or /. For example, to find all the files anywhere on the D: drive that begin with xm, one might type:
As with all the wildcard constructs, the indefinite directory construct can be used completely arbitrarily. It can even be used several times in the same wildcard. But do notice if you do that, there is a possibility of getting the same file listed more than once:
This can happen if there’s more than one possible way to match the same pathname. In this example, the a* part could matched either Andrew or Accounts with the first ... matching either u\Andrew or u and the second ... matching either Accounts or just zero levels.
When you specify a sequence of wildcard patterns and none of them match, it’s normally treated as an error. In this example, the first command causes an error because there’s no file or directory name with a “z” in it. The second command executes without error because, out of the sequence of patterns, there’s at least one match.
In this context, the fact that alternation caused something to be generated is not the same as a match. In the next example, {zork,gadzooks,*z*}.csh is the same as zork.csh gadzooks.csh *z*.csh; only the last element involves any matching, and it fails.
The nonomatch variable lets you control how a wildcard failure is treated. It works just the way nonovar works when you reference to a non-existent variable.
Hamilton C shell expands out wildcards before it invokes the application you name. This is not what the copy, xcopy, rename, and del commands expect! Suppose there are two files, file.a and file.b on your diskette a:, that you wanted to copy to your current drive. Under cmd.exe, it would be natural to type:
The destination is implicit. xcopy understands the wildcarding to mean “copy everything on drive a: to the current disk and directory.” That is not what would happen under the C shell! Because the wildcard would be expanded first, it would act instead as if you had typed:
Do you see what happens? If wildcarding is done first, the xcopy command sees just the two filenames and figures you mean to copy one right over the other. file.b is lost! For this reason, the normal startup.csh file contains some carefully constructed aliases and procedures to intercept the copy, xcopy, rename and del commands:
The way this works by saving the current value of nowild (which tells whether wildcarding is should be done), turning off wildcarding, invoking the copy, xcopy, rename or del command, then restoring the wildcarding state. s is a temporary variable that gets discarded after its been used.
Be sure to always invoke copy, xcopy, rename and del via these aliases. If you encounter other applications that really must do their own wildcarding, use this same technique with them.
Wildcarding and pattern matching
Filename completion
Predefined environment variables
Predefined aliases
Builtin and predefined procedures
Order of evaluation
Tutorial: Filename completion