I'm currently trying to loop through a set of directories, but only the ones I care about.

$ ls -d */
cfdpost_statefiles/     p050L0260/  p050L0510/  p060L0390/  p070L0260/  p070L0510/  p092L0390/  p097L0260/  p110L0390/  p131L0325/  p150L0510/  profiles/
ERCOFTAC_TestSettings/  p050L0390/  p060L0260/  p060L0510/  p070L0390/  p084L0510/  p094L0325/  p100L0510/  p125L0510/  p136L0260/  p162L0260/  settings/

I want to match all the p###* directories except for the ones beginning with p125 and p150.

If I just do patterns with a pipe, I get:

$ for dir in ./p(125|150)*(/); echo $dir

However, if I try and use the ^ like it shows in it's documentation:

$ for dir in ./p^(125|150)*(/); echo $dir
zsh: no matches found: ./p^(125|150)*(/)

Any ideas how to proceed?


The EXTENDED_GLOB options needs to be set for zsh.

To see if it's been set, run setopt to display the options that have been set:

$ setopt | grep glob

If it isn't set, run setopt extended_glob.

NOTE: this will cause the ~, ^, and # to not be expanded on.

The issue in my case was that, although I set this option in the shell, I was running the for loop in a script. The script starts its own shell to run in and thus didn't have the option set.

To fix this particular issue, put setopt extendedglob in the script itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.