Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: ${name/pattern/repl} with negated pattern
On May 15, 2:26pm, Roman Neuhauser wrote:
}
} > a=(x/foo y/bar x/baz y/qux)
} > echo ${a/#(^x)\/*} # ok
} x/foo x/baz
} > echo ${a/#^x\/*} # wtf
} /foo /baz
}
} what's happening here?
You've forgotten that parameter expansion is a pattern match rather than
a filename glob and that slashes have no special significance in pattern
matching, so ^x\/* is ^(x\/*) despite the "higher precedence" mention.
} while i'm here: the whole workaround is cumbersome, you need to negate
} the pattern (might be difficult in some cases) and actually get as many
} items back as are in the input array (thus the nested parameter
} expansion, ${(j:,:)a/#(^x)\/*} produces "x/foo,,x/baz,").
You can work out why this happens if you read through the "rules for
substitution" in the Parameter Expansion section. The short answer is
that you have to use a nested expansion to cause the array to be fully
normalized before you join its elements:
${(j:,:)${a/#(^x)\/*}}
If you're going to put that inside double quotes, additional gyrations
are required.
} i hoped zsh would have a direct way to expand only those items of an
} array that match a pattern, eg. ${@:/#sh\/*}.
Not sure what #sh\/* means (you can't start an extendedglob pattern with
the "#" repetition operator, though for some reason parameter expansion
doesn't gripe about it) but the (M) qualifier with the :# susbstition
should do what you want:
${(M)@:#pattern}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author