In find -name "*.mp3"
, there is an asterisk before the .mp3. Doesn't the *
match the character before it any number of times? But there is nothing in front of the asterisk, so what does the *
do? Or is it because the find
command does not use regular expressions? So, is the .
in .mp3 a regular expression character or does find
just interprets it as a period to match?
The
-name
predicate takes a glob, not a regular expression.In a regular expression,
*
would match zero or more of the preceding item. But since this is a glob, it matches zero or more of any character. That is,*
in a glob means the same thing as.*
in a regular expression.In a regular expression,
.
would match exactly one of any character. But since this is a glob, it is not treated specially, and simply matches a literal.
character. That is,.
in a glob means the same thing as\.
or[.]
in a regular expression.If you did want to match a single occurrence of any character in a glob, you would use
?
. In a glob,?
means the same thing as.
in a regular expression. This is quite different from?
in a regular expression, which matches zero or one of the preceding item (i.e., makes the preceding item optional).The only syntax that's mostly the same in both globs and regular expressions is character classes enclosed in
[
]
. For example,[aeiou]
matches any character that is eithera
,e
,i
,o
, oru
. If you write a[
]
-delimited character class that works in most regex dialects, it's likely to be a character class with the same meaning when used in a glob, too.Other than as the operand to
find
's-name
and-iname
predicates, another place where globs are widely used is by your shell. Unquoted globbing metacharacters are expanded by your shell automatically into a list of separate arguments corresponding to the filenames they match.This is why it's important to quote such a pattern when passing it to
find
. If you don't, your shell will try to expand it. If your shell does expand it,find
won't see the pattern itself, but instead the result of its expansion. This is undesirable and often confusing.Note that your shell (probably bash, but this is true of Unix-style shells in general) will not, as its default behavior, expand
?
or*
to match a leading dot in a filename. For example, unless you've told it to behave otherwise, your shell expands?
to the filenames in the current directory that are one character long, other than.
, even though a.
entry is always present. And it expands*
to the filenames in the current directory that don't start with.
. (In bash,shopt -s dotglob
would change this for the shell instance you run it in, andshopt -u dotglob
would restore the default behavior.) It is only leading dots that are special, not other dots.This differs from the behavior of
find
's-name
and-iname
predicates, where?
and*
are always permitted to match a leading.
.The Asterisk (commonly known as the "Wildcard Operator") says that
find
should return all files with the.mp3
extension.Because you use double quotes,
bash
tries to expand the"*.mp3"
glob.If there are some
*.mp3
files in the current directory, their names will replace the glob.To demonstrate, put an
echo
at the beginning of the line, e.g.echo find ...
.If you use single quotes (
'
), glob expansion is not performed.Use "
'*.mp3'
" instead of ""*.mp3"
".