Powerfool
Powerfool

Reputation: 155

zsh glob qualifiers in middle of path

Suppose I have the following directory structure:

$ mkdir -p a/1
$ ln -s a b

Globbing for directories, I get the directory within the symlink too:

$ print -l */*(/)
a/1
b/1

How can I restrict the globbing for the first directory level to directories only, excluding symlinks? The obvious doesn't work:

$ print -l *(/)/*(/)
zsh: bad pattern: *(/)/*(/)

More generally, how can I specify glob qualifiers for intermediate path components? In spirit:

$ print -l a(...)/b(...)/c(...)/d(...)/e(...)/f(...)

where (...) denotes glob qualifiers for the respective path components.

Upvotes: 6

Views: 6401

Answers (2)

Marlon Richert
Marlon Richert

Reputation: 6985

If you don't mind a itself appearing in your list, then this should do the trick:

# ** doesn't follow symlinks.
print -l **/*(/)

If you want only subdirs, then you'll need to use two patterns, instead of one:

# Make an array with all dirs that are in the pwd.
tmp=( *(/) )

# $^tmp applies brace expansion on the array.
# (N) ignores 'file not found' errors, in case tmp contains dirs w/out children.
print -l $^tmp/*(/N)

This way, you can also have different glob qualifiers for each part in your path, but you'll have to make a separate parameter for each.

Upvotes: 1

gvalkov
gvalkov

Reputation: 4097

The documentation suggests that glob qualifiers may be used only at the end of a pattern:

Patterns used for filename generation may end in a list of qualifiers enclosed in parentheses. The qualifiers specify which filenames that otherwise match the given pattern will be inserted in the argument list.

While less convenient than a glob, what you are trying to achieve could be done with find:

find -H . ! -path . -type d -links 2 | xargs
./a/1 

Upvotes: 0

Related Questions