I want to list all .jpg files in all subdirectories using ls
.
For the same directory this works fine:
ls *.jpg
However, when using the -R
for recursiveness:
ls -R *.jpg
I get:
zsh:no matches found: *.jpg
Why does this not work?
Note: I know it can be done using find
or grep
but I want to know why the above does not work.
CodePudding user response:
The program ls
is not designed to handle patterns by itself.
When you run ls -R *.jpg
, the pattern *.jpg
is not directly passed to ls
. The shell replaces it by a list of all files that match the pattern. (Only if there is no file with a matching name, ls
will see the file name *.jpg
and not find a file of this name.
Since you are using zsh
(with the default setting setopt nomatch
), it prints an error message instead of passing the pattern to ls
.
If there are matching files, e.g. A.jpg
, B.jpg
, C.jpg
, the command
ls *.jpg
will be run by the shell as
ls A.jpg B.jpg C.jpg
In contrast to this, find
is designed to handle patterns with its -name
test. When using find
you should make sure the pattern is not replaced by the shell, e.g. by using -name '*.jpg'
or -name \*.jpg
. Otherwise you might get unexpected results or an error if there are matching files in the current directory.