I wrote the following snippet to delete several subdirectories selectively from a common ancestor. It doesn't work, but I can't tell why.

for x in *; 
do rm -r "$x/foo/bar/{a*,b,c,d,g*}"; 

I get "no such file or directory" errors when I run it, even though I know that the folders exist.

  • 3
    In zsh, you don't need the quotes at all. You do need the quotes in other shells. Except that here, you can write rm -r */foo/bar/{a*,b,c,d,g*} (in zsh, make that rm -r */foo/bar/{a*,b,c,d,g*}(N), where the N glob modifier indicates that you want to skip non-matching patterns rather than signal an error). – Gilles Nov 18 '11 at 10:33
  • @Gilles, Not even if the path contains spaces? – Iulian Onofrei Feb 22 '17 at 10:11
  • @IulianOnofrei Indeed. In zsh (except if explicitly configured for closer sh compatibility), $foo expands to the value of foo unless that value is empty. It doesn't do splitting and globbing on the value like other shells in the sh family. – Gilles Feb 22 '17 at 10:59
  • @Gilles, So you need quotes if x in the OP's example points at a directory with spaces in name, right? – Iulian Onofrei Feb 22 '17 at 13:15
  • @IulianOnofrei You do in other shells, because they do splitting and globbing on unquoted substitutions. But not in zsh, because it doesn't split or glob unless explicitly told to. – Gilles Feb 22 '17 at 13:22

Brackets won't expand inside double quotes. Try this:

for x in *; 
do rm -r "$x/foo/bar/"{a*,b,c,d,g*}; 

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.