26

I have been using zsh globbing for commands such as:

 vim **/filename
 vim *.html.erb

and so on, but when I type in something like:

 find . -name *mobile*

I get the response:

 zsh: no matches found: *mobile*

Why?

ovatsug25
  • 7,786
  • 7
  • 34
  • 48

3 Answers3

56
find . -name *mobile* # does not work

vs

find . -name '*mobile*' # works

The difference is due to the steps that the shell takes when it parses a line. Normally, the shell expands any wildcards it finds before it runs the command. However, the single quotes mark the argument as being a literal, which means that the shell does not perform wildcard expansion on that argument before running the command.

To demonstrate the difference, suppose you are in a directory with the following files:

$ tree
./
mobile.1
dir/
    mobile.2

In the first case, without single quotes, zsh will process as follows:

  • expand the glob, rendering simply mobile.1 (because that is the only matching filename in the current directory
  • pass the result to find, hence:
find . -name mobile.1

So find will only look for files named literally mobile.1

In the second form, with single quotes, the entire glob will be preserved and passed to find:

find . -name *mobile*

Which means that find will look for any filename containing the string "mobile".

The important thing to note here is that both zsh and find support the same wildcard syntax; by using single quotes, you induce find to handle the wildcards in this case rather than zsh.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Swiss
  • 5,556
  • 1
  • 28
  • 42
4

Turns out that all you have to do to solve the problem is add some quotes around the input:

find . -name '*mobile*'

I don't really have an answer as to why just yet...and the documentation doesn't have an something that sticks out to me, but let me know if you know the answer!

ovatsug25
  • 7,786
  • 7
  • 34
  • 48
1

For archival purposes, here is my substantial edit/reformatting of @Swiss's response above. The edit queue has been full every time I tried to edit, for hours, so I want to preserve this for future reference. I hope it's deemed to be constructive.

To be super-clear it's a revision of another person's work.


find . -name *mobile* # does not work

vs

find . -name '*mobile*' # works

The difference is due to the steps that the shell takes when it parses a line. Normally, the shell expands any wildcards it finds before it runs the command. However, single quotes marks the argument as being a literal, which means that the shell does not preform wildcard expansion on that argument before running the command.

To demonstrate the difference, suppose you are in a directory with the following files:

$ tree
./
mobile.1
dir/
    mobile.2

In the first case, without single quotes, zsh will process as follows:

  • expand the glob, rendering simply mobile.1 (because that is the only matching filename in the current directory
  • pass the result to find, hence:
find . -name mobile.1

So find will only look for files named literally mobile.1

In the second form, with single quotes, the entire glob will be preserved and passed to find:

find . -name *mobile*

Which means that find will look for any filename containing the string "mobile".

The important thing to note here is that both zsh and find support the same wildcard syntax; by using single quotes, you induce find to handle the wildcards in this case rather than zsh.

Philip
  • 323
  • 3
  • 13