Patterns for File Names: Wildcards

Last modified: Aug 29, 2023
Contents:
 

In the command examples we have used so far, we have always written a single file path or a single text string. In many cases, however, we want to supply commands with a whole list of files or text strings. Typing out the whole list, one at a time, would be tedious, so we usually write some kind of pattern that describes multiple items instead.

1 Wild Cards

Whenever we have a command that can take multiple filenames, we can often write a single pattern for several files. Patterns for file names use wildcard characters, the most common of which is "*", which tells the shell (the program that reads your keyboard input, determines what command or program you want to run, then launches that program) to substitute any combination of zero or more characters that results in an existing file name.

Example 1: Try This: Wild cards in common commands
ls ~/playing
rm ~/playing/*
ls ~/playing

What files were matched by the wildcard pattern in the rm command?

ls /usr/include

Notice that there are a number of files ending with .h

cp /usr/include/m*.h /usr/include/s*.h ~/playing
ls ~/playing
ls ~/playing/se*
ls ~/playing/sq*.h
ls ~/playing/se* ~/playing/sq*.h

Again, note the use of the wildcard to form a pattern for multiple file names. In cases, like this, where there are multiple possible matches, the shell forms a list of all the matches. So

  • the earlier rm command actually saw a list of all the files in the ~/playing directory.
  • The cp command saw all the files in the in the /usr/include directory whose names began with “m” or “s” and ended with “.h”.
  • The various ls commands saw restricted sets of files based upon the non-special characters intermixed with the wildcards.

One good way to figure out what files will match a wildcard pattern is to use the echo command. echo simply prints out its arguments. But since the arguments in the command line are processed by the shell before invoking the echo program, any wildcard patterns will have already been expanded.

Example 2: Try This: Showing the effects of a wildcard pattern
ls /usr/include
echo /usr/include
echo /usr/include/*.*
echo /usr/include/*

The difference between the last two may be subtle. The “.” pattern will match only files that contain a “.”. Unlike Windows, Unix does not require file names to end with a period and a three-letter extension. Some sort of period and extension is common, but directory names and executable programs often have no extension and no period. (In Windows, you can create a file with an empty extension, but Windows insists on adding a period at the end.)

echo /usr/include/f*.*
echo /usr/include/*f*.*

Many of the commands that we have already looked at will allow you to specify multiple files to operate on at one time. The easiest ways to give multiple files will be to use wildcards.

grep is a program for searching files to find lines that match a certain pattern. We’ll look at how to write those patterns in a later lesson, but in the meantime we can make good use of grep to search for lines containing a specific text string.

grep commands look like:

grep flags pattern one-or-more-file-paths

Example 3: Try This: Operating on multiple files at once

Do the following. Make sure that you understand what you are seeing in each case.

ls ~cs252/Assignments/emacsAsst/*.txt
grep Title ~cs252/Assignments/emacsAsst/*.txt
grep Author ~cs252/Assignments/emacsAsst/*.txt
grep title ~cs252/Assignments/emacsAsst/*.txt
grep -i title ~cs252/Assignments/emacsAsst/*.txt
grep -v title ~cs252/Assignments/emacsAsst/*.txt
grep -l constitution ~cs252/Assignments/emacsAsst/*.txt
grep constitution ~cs252/Assignments/emacsAsst/8*.txt

Each time you use a wildcard pattern, the command shell expands that to a list of files, separated by spaces:

echo ~cs252/Assignments/emacsAsst/*.txt
echo ~cs252/Assignments/emacsAsst/8*.txt

What do you get if you have a list of files spearated by spaces, followed by another list of files separated by spaces? Answer: A longer list of files, separated by spaces.

echo ~cs252/Assignments/emacsAsst/*.txt /usr/include/*.h
grep -l large ~cs252/Assignments/emacsAsst/*.txt
grep -l large /usr/include/*.h
grep -l large /usr/include/*.h ~cs252/Assignments/emacsAsst/*.txt