Filename matching
Filename matching, also called pattern matching, is used any time it is desirable to specify more than one filename for a given command, function or process. It saves time by not requiring the typing out of each and every file name. For example, you might wish to remove all files ending with the extensions .1, .2, .3, and .4, to clear out your /var/log
directory of old logs you have no interest in.
Modern shells let you specify multiple files using various special matching characters (called regular expressions). When you specify a pattern, each file in a given directory is checked against that pattern. Some of the more common formats you'll see:
*
- matches one or more characters in a filename. For example,foo*bar
matches the filesfoobazbar
,foobar
,foolbar
andfoolebar
, but not the filefoo/bar
, which is in a subdirectory.
?
- matches any single character in a filename. For example,foo.?
matchesfoo.1, foo.a, foo.z
but notfoo.42
.
{name,name,name}
- matches any of the listed strings in curly braces. Any one of those matches will be considered valid. For example,foo{bar,baz}
matches the filesfoobar
andfoobaz
, but notfoobarbaz
.
Multiple types of patterns can be mixed together. For example, this pattern:
r*.{txt,bat,sh}
Would match all files beginning with the letter r, and ending in .txt, .bat, or .sh.
This pattern:
*/*
Would match all files in every subdirectory of the current directory, but not any files in the current directory, nor any in deeper subdirectories.
Sometimes it is necessary to protect names from matching/expanding. Suppose you have file a.mp3 in current directory and want to search for more MP3's with the command:
$ find / -name *.mp3
Due to pattern expansion, it is treated as:
$ find / -name a.mp3
so search will be performed only for files named a.mp3 elsewhere in the filesystem. Intended results can be obtained with:
$ find / -name '*.mp3'
Apostrophes protects string from expansion and command obtains string *.mp3.