Wildcards

Team-Fly    

Solaris™ Operating Environment Boot Camp
By David Rhodes, Dominic Butler
Table of Contents
Chapter 5.  Shells


UNIX gives you various ways to be lazy, and one of the most useful is in the use of wildcards. If you are familiar with wildcards you may have thought that UNIX commands must be written to a standard so that they treat the wildcard characters in the same way. UNIX commands do have many standards, but this is not one of them. UNIX commands in general wouldn't know a wildcard character if it had "I AM A WILDCARD" tattooed across its chest.

Wildcards are, instead, dealt with by the shell. They are used as a way of matching filenames; the man pages refer to this as File Name Generation.

The wildcard characters are:

  • *

  • ?

  • []

The asterisk (*) matches zero or more occurrences of any character. The question mark (?) matches a single character. The square brackets ([ ]) will match any of the characters included within the brackets.

For example, [A-L] would match any single character in the range A-L inclusive. This is case-specific; if you wanted to match all characters in the range A to L, you would specify [A-La-l]. If the first character after the "[" is "!" then it means "NOT." If you want to match a minus sign, put it just after the "[" or just before the "]" and it will not be treated as meaning a range of characters.

The following examples show how the wildcard characters can be used. They all use the ls command, but wildcard characters can be used with any command that can take filenames as parameters:

 $ ls abc def frank fred freddie freddy test test1 test11 test12 test2 test21 $ 

The first example is nice and simple; it will match all files that begin with the letter "f."

 $ ls f* frank fred freddie freddy $ 

The next example uses "?," which will match any single character. So here we get the files with a name beginning with "test" followed by any single character:

 $ ls test? test1 test2 $ 

The pattern used in this example (???) matches all files with a name exactly three characters long:

 $ls ??? abc def $ 

The final two examples make use of the square brackets, which match one of a range of characters:

 $ ls test1[1-5] test11 test12 $ 

In the previous example, we have said we want to match all files whose names begin "test1" followed by a single character that can be any in the range "1" to "5." If there had been a file called test123, it would not have matched since it has an extra character in its name and the square brackets only match a single character.

In this last example, we match all files with a first letter in the range "a" to "m":

 $ ls [a-m]* abc def frank fred freddie freddy $ 

These show a fair selection of wildcard examples. However, the best way of getting to grips with them is by practice (rm is probably not a good command to use for practicing wildcard usage).

Wildcard patterns can be grouped together into a pattern list. This is formed by putting the pipe symbol "|" between each pattern. The pattern list can then be placed within the constructs listed in Table 5.2 to offer more advanced filename matching.

Table 5.2. Advanced Wildcard Usage

Construct

Meaning

?(pattern list)

Will optionally match any one of the included patterns.

*(pattern list)

Will match zero or more occurrences of the included patterns.

+(pattern list)

Matches one or more occurrences of the included patterns.

@(pattern list)

Matches exactly one of the supplied patterns.

!(pattern list)

Will match anything except one of the supplied patterns.

For example:

 $ ls ?(a*|*2) abc test12 test2 $ 

Here, a file matched if it either began with an "a" or ended with a "2."

Additional Notes on Wildcards

Most UNIX commands do not know what a wildcard is, but what about those that do? If the shell sees the wildcard, then the shell will replace it with the files that it matches. Even if the command does know about wildcards, it won't see it.

An example of a command that does know about wildcards is find. The find command is used to find files on your system that match certain criteria. This includes finding:

  • Files with a certain name

  • Files whose name matches a certain pattern of wildcards

  • Files that haven't been accessed for a certain amount of time

  • Files that are bigger than a certain size

  • Files that are owned by a certain user

  • Files that are a certain type (e.g., named pipes or directories)

Find doesn't just look for the first file that matches the search criteria. It will keep searching and report all the files that match, so it is great when you need to provide a list of files that can be passed to another command (such as a backup utilitysee Chapter 22, "Backing Up and Restoring the System").

Full details of using find are described in the Solaris man pages. Here, however, we have a basic example so we can demonstrate how to use wildcards without the shell getting its hands on them first.

If you wanted to find all the files (including directories) called fred on the system, searching from the current directory downward you would use find as follows:

 # cd / # find . -name fred -print ./fred ./export/home/fred ./var/mail/fred # 

This command means "search for all files called fred starting in the current directory and print the results to the screen." The default action is to print to the screen, so the "-print" can be left off, though people tend to use it anyway. Because we used "." to specify "current directory," all the paths returned begin with a "." (they are relative to the starting directory). If we have put a slash ("/") to mean "start" at the root directory, the paths returned would have begun with a "/" and would be absolute path names. If you ever search for a file from the root directory as any user other than root, expect to get lots of errors back for all the directories that you do not have permission to access. This would be a good time to redirect all error messages to /dev/null. An example of doing this is shown later in the chapter in the section "File Redirection" on page 119.

Now we get to the wildcards.

If we wanted to find all files from the current directory that began with an "f" then we would use the "*" wildcard after the "f" as follows:

 # cd / # find . -name f* -print 

Now we can't show the next bit as there are three possible outcomes and the actual one is dependent on what other files exist in the directory from which the command was run.

  • Outcome 1: Because the shell deals with wildcards, it will look for files in the current directory that match the wildcard pattern specified. If there are no files that match, the pattern will be left as you typed it and the above command would find all the files under the current directory that begin with an "f."

  • Outcome 2: Because the shell deals with wildcards, it will look for files in the current directory that match the wildcard pattern specified. If there were one file in the current directory that began with an "f" the shell would replace the "f*" with that filename. Thus, in this case, the command you typed would find all files with that name, NOT all files that begin with "f."

  • Outcome 3: Because the shell deals with wildcards, it will look for files in the current directory that match the wildcard pattern specified. If there were several files in the current directory that began with "f" the shell would replace the "f*" with all the names that match separated by a space. The outcome this time would be that, rather than the find command going off and doing the wrong thing, it will actually fail with a syntax error as only one filename can be supplied with the "-name" option.

To guarantee that the find command runs as expected, any filename containing a wildcard should have quotes around it (single or double). The shell cannot see wildcards when they are in quotes so the find command sees it and deals with it itself. We will look at hiding things from the shell in more detail in the next section.

If you are used to using wildcards on PCs you will use "*.*" to match all files. In UNIX, "*.*" will match all files that contain a dot, but not those that don't. To match all files in a directory use "*" (with no dot).

If a filename begins with a dot, it will not be matched by a single asterisk; you will need to specify the dot (i.e, ".*").


    Team-Fly    
    Top
     



    Solaris Operating Environment Boot Camp
    Solaris Operating Environment Boot Camp
    ISBN: 0130342874
    EAN: 2147483647
    Year: 2002
    Pages: 301

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net