Extended globbing¶
luish can expand filename patterns as zsh does: **/ matches any number of directories, and a glob qualifier in
parentheses after a pattern selects files by type, size, age and more, and can sort and change the result. Options
also decide what a pattern that matches nothing gives, and whether patterns match hidden files (see
below). All are off by default, so that scripts behave as in other
POSIX shells. Turn the first two on with:
setopt glob.star glob.bare_qualifiers
For example:
ls **/*.md # Markdown files in this directory and below
ls -d *(/) # directories
ls *(.) # regular files
rm **/*.orig(.N) # no error if there are none
vi *(.om[0]) # the most recently modified file
du -sh **/*(.Lm+100) # files over 100 MiB
Recursive globbing (glob.star)¶
With setopt glob.star, a path component that is exactly ** and is followed by / matches zero or more
directories. **/*.md matches x.md, a/y.md and a/b/z.md; a/**/ lists a/ and every directory below it.
Hidden directories (whose name starts with
.) are not entered, unless theDqualifier is given. Symbolic links to directories are not followed.***/follows them, and stops at a link to a directory it is already in.**anywhere else (as the last component, or next to other characters, as ina**) is the same as*.A quoted
**is not special.Without the option,
**is the same as*, as in other POSIX shells.
As in zsh, the matches are sorted as full paths, so a.md comes before a/b.md.
Glob qualifiers (glob.bare_qualifiers)¶
With setopt glob.bare_qualifiers, parentheses at the end of a word hold a list of qualifiers: *(/), **/*.c(.om). The
parentheses must be the last thing in the word and contain no blanks, quotes or $. A word with a qualifier is a
pattern even if it has no *, ? or [, so file(N) expands to file if it exists and to nothing otherwise.
Function definitions such as f() and f( ) are not affected.
As in zsh’s sh emulation, a qualifier can also come from an unquoted expansion: with p='*(/)', echo $p lists
the directories. Quote the expansion ("$p") to keep the text as it is.
Qualifiers that test files select the matches that pass every test. , separates alternatives: *(/,@) selects
directories and symbolic links.
Qualifier |
Selects |
|---|---|
|
directories |
|
regular files |
|
symbolic links |
|
sockets |
|
named pipes (FIFOs) |
|
executable regular files |
|
device files, block devices, character devices |
|
readable, writable, executable by the owner |
|
readable, writable, executable by the group |
|
readable, writable, executable by others |
|
setuid, setgid, sticky |
|
owned by the effective user, group |
|
owned by the user or group id: a number, or a name between delimiters, as in |
|
on device number dev |
|
with fewer than, more than or exactly n hard links |
|
with a size less than, more than or equal to n units, rounded up. The unit is bytes, or |
|
accessed, modified or changed less than, more than or exactly n units ago. The unit is days, or |
^ negates the tests after it, and - makes the tests after it look at the target of a symbolic link rather than
the link: *(-/) also selects links to directories, and *(-@) selects broken links.
Other qualifiers change the result:
Qualifier |
Effect |
|---|---|
|
if nothing matches, the word is removed (otherwise it is left as it is) |
|
patterns match names starting with |
|
names that contain numbers sort numerically ( |
|
sort in ascending or descending order: by name ( |
|
only the n-th match, or the n-th to the m-th, after sorting. They count from 0, and negative numbers count from the end ( |
|
add |
|
add a character after each name for its type, as |
|
modifiers, at the end of the list: remove the last path component (head; |
A bad qualifier is an error, with status 1, as in zsh: *(Z) gives *(Z): bad glob qualifier: unknown file attribute: Z.
As in zsh with globsubst, the qualifier may come from an expansion, so echo $PS1 fails if PS1 ends in
%(...); quote the expansion (echo "$PS1") to keep it literal.
Differences from zsh¶
**/needssetopt glob.star, and qualifiers needsetopt glob.bare_qualifiers(zsh’sbareglobqual; zsh has**/on by default, and qualifiers on outside itsshemulation).If nothing matches, the pattern is left as it is by default, as with
setopt nonomatchin zsh (and in other POSIX shells);setopt glob.failis zsh’s default.With
glob.failorglob.fail_all, a pattern that matches nothing inevalexits a script, as other expansion errors do (as in dash); in zsh,evalreturns 1.Subscripts count from 0, as in zsh’s
shemulation (which setsKSH_ARRAYS); in its native mode they count from 1.Not supported yet: the
e,+,f,F,YandPqualifiers,(#q...), modifiers other than those above, and the extended patterns of zsh’sEXTENDED_GLOB(^,~,#). Unknown sort keys and modifiers are errors (zsh ignores some of them).Files that sort the same (with
oorO) stay in name order; in zsh their order is unspecified.