Sams Teach Yourself Shell Programming in 24 Hours
(Publisher: Macmillan Computer Publishing)
Author(s): Sriranga Veeraraghavan
ISBN: 0672314819
Publication Date: 01/01/99

Previous Table of Contents Next


Using the ? Wildcard

One limitation of the * wildcard is that it matches one or more characters each time.

As an example, consider a situation where you need to list all files that have names of the form ch0X.doc, where X is a single number or letter. It seems like the command

$ ls ch0*.doc

would produce the appropriate match, but the actual output might look like:

ch01-1.doc  ch010.doc   ch02.doc    ch03-2.doc  ch04-1.doc  ch040.doc
⇒ch05.doc    ch06-2.doc
ch01-2.doc  ch02-1.doc  ch020.doc   ch03.doc    ch04-2.doc  ch05-1.doc
⇒ch050.doc   ch06.doc
ch01.doc    ch02-2.doc  ch03-1.doc  ch030.doc   ch04.doc    ch05-2.doc
⇒ch06-1.doc  ch060.doc

In order to match only one character, the shell provides you with the ? wildcard. You can rewrite the command using this wildcard:

$ ls ch0?.doc

Now you see that the output matches only those files you are interested in:

ch01.doc  ch02.doc  ch03.doc  ch04.doc  ch05.doc  ch06.doc

Say that you now want to look for all files that have names of the form chXY, where X and Y are any number or character. You can use the command

$ ls ch??.doc

to accomplish this.

Matching Sets of Characters

Two potential problems with the ? and * wildcards are

  They match any character, including special characters such as hyphens (-) or underlines (_).
  You have no way to indicate that you want to match only letters or only numbers to these operators.

Sometimes you need more control over the exact characters that you match. Consider the situation where you want to match filenames of the form ch0X, where X is a number between 0 and 9. Neither the * or the ? operator is cut out for this job.

Fortunately, the shell provides you with the capability to match sets of characters using the [ wildcard. The syntax for using this wildcard is

command [characters]

Here command is the name of a command, such as ls, and characters represents the characters you want to match. For example, the following command fulfills the previous requirements:

$ ls ch0[0123456789].doc
ch01.doc  ch02.doc  ch03.doc  ch04.doc  ch05.doc  ch06.doc

One thing that you might have noticed is that you had to list all the characters that you wanted matched. The shell provides a mechanism to shorten the list. For example, the command

$ ls ch0[0-9].doc

produces the same list of files. As you can probably guess, this is most useful when you’re trying to match sets of letters. For example,

$ ls [a-z]*

lists all the files starting with a lowercase letter. To match all the files starting with uppercase letters use the following:

$ ls [A-Z]*

The [ wildcard also enables you to combine sets by putting the sets together. For example,

$ ls [a-zA-Z]*

matches all files that start with a letter, whereas the command

$ ls *[a-zA-Z0-9]

matches all files ending with a letter or a number.

As you can see from the previous examples, the maximum amount of flexibility in filename substitution occurs when you couple the [ wildcard with the other wildcards.

Negating a Set

Consider a situation where you need a list of all files except those that contain the letter a. You have two approaches to solving this problem:

1.  Specify all the characters you want a filename to contain.
2.  Specify that the filename should not include the letter a.

If you choose the first approach, you need to construct a set of all the characters that your filename can contain. You can start with:

[b-zA-Z0-9]

This set does not include the special characters that are allowed in filenames. Attempting to include all these characters creates a huge set that requires complicated quoting. An approximation of this set is

[b-zA-Z0-9\-_\+\=\\\'\"\{\[\}\]

Compared to this, the second approach is much better because you only need to specify the list of characters that you don’t want.

The [ wildcard provides you the capability to match all characters except those that are specified as the set. This is called negating the set, which you can accomplish by specifying the ! operator as the first character in a set. The syntax is

command [!characters]

Here, command is the name of a command, such as ls, and characters is the set of characters that you do not want to be matched. For example, to list all files except those that start with the letter a, you can use the command

$ ls [!a]*


Previous Table of Contents Next