This is kind of a weird question, seeing as zsh is the only shell with this feature. It's called glob qualifiers. The manual is, as usual, rather terse and devoid of examples. The Zsh-lovers page has a few examples. Googling zsh "glob qualifiers"
turns up a few blog posts and tutorials. You can also search for "glob qualifier"
on this site.
The basics: glob qualifiers are in parentheses at the end of the glob. The most useful ones are the punctuation signs to select only certain file types.
echo *(/) # directories
echo *(.) # regular files
echo *(@) # symbolic links
echo *(-/) # directories and symbolic links to directories
There are other qualifiers to filter on metadata such as size, date and ownership.
# files owned by the user running zsh, over 1MB, last modified more than 7 days ago
echo *(ULm+1m+7)
Glob qualifiers can also control the order of matches, and restrict the number of matches.
echo *(Om[1,10]) # The 10 oldest files
You can set up arbitrary filters by calling a function, with the +
qualifier (you can even put the code inline with the e
qualifier, if you don't mind the tricky quoting).
Note that unfortunately all of this only works on globs. If you want to build a list of file names this way, you need to filter when you're globbing. If you want to filter a list that you've already built, there's a completely different syntax, parameter expansion flags, which can only perform simple text filtering ("${(@)ARRAY:#PATTERN}"
).
Zsh's extended glob operators support matching over /
(unlike ksh's, even in zsh's implementation). Zsh's **/
is a shortcut for (*/)#
(*/
repeated 0 or more times). So all I need to do is replace that *
by ^.svn
(anything but .svn
).
print -l (^.svn/)#
Neat!
Best Answer
You can disable the
PATTERN(QUALIFIERS)
syntax by unsetting thebare_glob_qual
option:If the option
extended_glob
is set (and you should set it, the only reason not to set it is for backward compatibility with rare scripts that use unusual syntax), then there is another syntax for glob qualifiers:PATTERN(#qQUALIFIERS)
. So you can still use glob qualifiers, which are one of zsh's killer features, but you'll have to type a bit more.Zsh lets you disable wildcard expansion (globbing) altogether, and this looks like a better choice for you. If a command is prefixed by
noglob
, then no globbing is performed on its arguments. For example, to be able to type URLs containing?
as arguments towget
, I havealias wget='noglob wget'
. If you setalias ag='noglob ag'
, you can typeag mymethod(param)
.If
ag
takes both a search pattern and file names as arguments, then disabling globbing is not good. If you're able to parse the arguments ofag
, then you can perform wildcard expansion on them. I don't know the syntax ofag
, so I'll give an example where I assume thatag
only takes options that don't take arguments, and that its first non-option argument is a pattern and the rest are files.