30

Say I have a folder with three files:

foo1
foo2
bar

1. If I run

list_of_files=$(print foo*)
echo $list_of_files

I get: foo1 foo2

2. If I run

list_of_files=$(print bar*)
echo $list_of_files

I get: bar

3. However, if I run

list_of_files=$(print other*)
echo $list_of_files

I get: zsh: no matches found: other* (the variable $list_of_files is empty though)


Is there a way to ask zsh to not complain if it can't match a glob expansion?

My goal is to use the mechanism above to silently collect a list of files that match a given glob pattern.

4 Answers 4

40

Turn on the null_glob option for your pattern with the N glob qualifier.

list_of_files=(*(N))

If you're doing this on all the patterns in a script or function, turn on the null_glob option:

setopt null_glob

This answer has bash and ksh equivalents.

Do not use print or command substitution! That generates a string consisting of the file names with spaces between them, instead of a list of strings. (See What is word splitting? Why is it important in shell programming?)

20

The better way: for a in *(.N); do ... ; done. The N option makes zsh deliver an empty list to for, and for will iterate zero times.

Watch out for ls *.foo(.N); when ls receives an empty argument list, it lists all files instead of none. This is why I don't like NULL_GLOB (or its bash equivalent): It changes all the globs and easily breaks calls to e.g. ls.

3
  • Fancy seeing your answer here @arnt, this is just what I needed.
    – gtd
    Feb 4, 2017 at 19:41
  • Why the . in (.N)? Other answers have (N) by itself, what is the difference? Apr 17, 2019 at 16:31
  • The question was about files, and . restricts the glob to match only files.
    – arnt
    Apr 17, 2019 at 16:46
4

I think you are looking for the NULL_GLOB option:

   NULL_GLOB (-G)
          If a pattern for filename generation has no matches, delete  the
          pattern  from  the  argument list instead of reporting an error.
          Overrides NOMATCH.
-1

Try this way:

list_of_files=$(print other*) 2>/dev/null

It will redirect error output from stderr to /dev/null and it won't display.

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .