How does find -name work?
The parameter passed to -name
is a filesystem glob pattern, the same as the you'd enter for other commands, such as ls -l *in
.
For each file it finds it compares the basename of the file to the pattern you passed. So when it finds /bin/foobar
it compares foobar
to *in
, doesn't match, skips; but with /bin/login
it compares login
to *in
and this does match, and so prints.
Now you need to be careful because *in
might be matched on the command line depending on files in the current directory.
So, for example:
$ find /bin -name *in
/bin
/bin/login
$ touch foobarin
$ find /bin -name *in
$
Notice the same find
command returned two different results.
We can see why if we set the shell to debug mode:
$ rm foobarin
$ set -x
$ find /bin -name *in
+ find /bin -name '*in'
/bin
/bin/login
$ touch foobarin
+ touch foobarin
$ find /bin -name *in
+ find /bin -name foobarin
$
The lines starting with a +
are what the shell interpreted the command entered. We can see that the second find
command expanded the *in
to match the existing filename.
Because of this it's recommended to quote names
$ find /bin -name '*in'
+ find /bin -name '*in'
/bin
/bin/login
Related videos on Youtube
Find
Updated on September 18, 2022Comments
-
Find almost 2 years
I can't for the life of me figure out how
find
with the test-name
works.I run
find / -name *in
and returns a bunch of results:/sbin /sbin/sulogin /dev/stdin
to name a few.
It's as if it performed filename expansion, but that happens before the shell runs the command, so that can't be it. Also because I don't have any files in the current directory that match
*in
. Plus, single quoting*in
yields the same results, which further supports that this can't be filename expansion.The documentation leads me to believe that
find
with-name
uses regular expressions, but the regex pattern*in
doesn't match the results I showed above.Can someone enlighten me?
-
mosvy about 5 years"It's as if it performed filename expansion, but that happens before the shell runs the command, so that can't be it." But that's exactly what it is! Only that instead of matching the
*in
pattern against the files from the cwd, it matches it against the the files from the directories it's walking through. -
mosvy about 5 years"The documentation kind of suggests that find with -name uses regular expressions" the documentation does not suggest such thing.
-
Freddy about 5 yearsIf you need regular expressions, you can use
-regex pattern
which is used to match the whole path (including slashes), while-name pattern
operates on the filename and uses shell patterns.
-
-
Find about 5 yearsThank you, that's helpful. When you say that we should quote names. Should it be, more precisely, single quote them?
-
Stephen Harris about 5 yearsThe quote will depend on how you want the command line to interpret your input, same as everywhere else. So if you're looking for a file called
$foo
then you may use'$foo'
but if you want to expand the variable then you may use"$foo"
. This isn't specific to thefind
command, but is how the command line works. -
Find about 5 yearsBut won't the variable be expanded just like
*
was when you used single quotes? EDIT: I understand this expansion occurs after the command is ran, contrarily to "regular expansion". -
Stephen Harris about 5 yearsNo; command line globs don't follow variable expansion. eg if we set
$ foo='*in'
then the command$ find /bin -name "$foo"
will give the debug output+ find /bin -name '*in'
which is exactly what we want.