Find Command – How Does find -name Work with Regular Expressions

findregular expression

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?

Best Answer

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 Question