Home > Back-end >  Why does ls not subset by filetype recursively (with -R)?
Why does ls not subset by filetype recursively (with -R)?

Time:10-09

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.

  • Related