Patterns for File Names: Wildcards
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 commandsls ~/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 patternls /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
-
The flags are optional. The ones we will use in this course are
- -i When comparing the pattern to the lines from the files, ignore differneces in upper/lower case characters.
- -v Instead of listing the lines of text that contain the pattern, list the ones to do not contain the pattern.
- -l Don’t list the lines that match the pattern, just list the names of the files contianing at least one such match.
-
The pattern, for now, will just be any string made up of letters and numbers.
-
The list of file paths indicates which files to examine. Wildcards will come in very handy here.
Example 3: Try This: Operating on multiple files at onceDo 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