Otherwise known as globbing, filename generation is quite extensive in zsh. Of course, it has all the basics:
% ls Makefile file.pro foo.o main.o q.c run234 stuff bar.o foo link morestuff run123 run240 sub file.h foo.c main.h pipe run2 run303 % ls *.c foo.c q.c % ls *.[co] bar.o foo.c foo.o main.o q.c % ls foo.? foo.c foo.o % ls *.[ˆc] bar.o file.h foo.o main.h main.o % ls *.[ˆoh] foo.c q.c
Also, if the EXTENDEDGLOB option is set, some new features are activated. For example, the ˆ character negates the pattern following it:
% setopt extendedglob % ls -d ˆ*.c Makefile file.pro link morestuff run2 run303 bar.o foo main.h pipe run234 stuff file.h foo.o main.o run123 run240 sub % ls -d ˆ*.* Makefile link pipe run2 run240 stuff foo morestuff run123 run234 run303 sub % ls -d ˆMakefile bar.o foo link morestuff run123 run240 sub file.h foo.c main.h pipe run2 run303 file.pro foo.o main.o q.c run234 stuff % ls -d *.ˆc .rhosts bar.o file.h file.pro foo.o main.h main.o
An expression of the form <x−y> matches a range of integers:
% ls run<200-300> run234 run240 % ls run<300-400> run303 % ls run<-200> run123 run2 % ls run<300-> run303 % ls run<-> run123 run2 run234 run240 run303
The NUMERICGLOBSORT option will sort files with numbers according to the number. This will not work with ls as it resorts its arguments:
% setopt numericglobsort % echo run<-> run2 run123 run234 run240 run303
Grouping is possible:
% ls (foo|bar).* bar.o foo.c foo.o % ls *.(c|o|pro) bar.o file.pro foo.c foo.o main.o q.c
Also, the string **/ forces a recursive search of subdirectories:
% ls -R Makefile file.pro foo.o main.o q.c run234 stuff bar.o foo link morestuff run123 run240 sub file.h foo.c main.h pipe run2 run303 morestuff: stuff: file xxx yyy stuff/xxx: foobar stuff/yyy: frobar % ls **/*bar stuff/xxx/foobar stuff/yyy/frobar % ls **/f* file.h foo foo.o stuff/xxx/foobar file.pro foo.c stuff/file stuff/yyy/frobar % ls *bar* bar.o % ls **/*bar* bar.o stuff/xxx/foobar stuff/yyy/frobar % ls stuff/**/*bar* stuff/xxx/foobar stuff/yyy/frobar
It is possible to exclude certain files from the patterns using the ˜ character. A pattern of the form *.c˜bar.c lists all files matching *.c, except for the file bar.c.
% ls *.c foo.c foob.c bar.c % ls *.c˜bar.c foo.c foob.c % ls *.c˜f* bar.c
One can add a number of qualifiers to the end of any of these patterns, to restrict matches to certain file types. A qualified pattern is of the form
pattern(...)
with single-character qualifiers inside the parentheses.
% alias l=’ls -dF’ % l * Makefile foo* main.h q.c run240 bar.o foo.c main.o run123 run303 file.h foo.o morestuff/ run2 stuff/ file.pro link@ pipe run234 sub % l *(/) morestuff/ stuff/ % l *(@) link@ % l *(*) foo* link@ morestuff/ stuff/ % l *(x) foo* link@ morestuff/ stuff/ % l *(X) foo* link@ morestuff/ stuff/ % l *(R) bar.o foo* link@ morestuff/ run123 run240 file.h foo.c main.h pipe run2 run303 file.pro foo.o main.o q.c run234 stuff/
Note that *(x) and *(*) both match executables. *(X) matches files executable by others, as opposed to *(x), which matches files executable by the owner. *(R) and *(r) match readable files; *(W) and *(w), which checks for writable files. *(W) is especially important, since it checks for world-writable files:
% l *(w) bar.o foo* link@ morestuff/ run123 run240 file.h foo.c main.h pipe run2 run303 file.pro foo.o main.o q.c run234 stuff/ % l *(W) link@ run240 % l -l link run240 lrwxrwxrwx 1 pfalstad 10 May 23 18:12 link -> /usr/bin/ -rw-rw-rw- 1 pfalstad 0 May 23 18:12 run240
If you want to have all the files of a certain type as well as all symbolic links pointing to files of that type, prefix the qualifier with a -:
% l *(-/) link@ morestuff/ stuff/
You can filter out the symbolic links with the ˆ character:
% l *(Wˆ@) run240 % l *(x) foo* link@ morestuff/ stuff/ % l *(xˆ@/) foo*
To find all plain files, you can use .:
% l *(.) Makefile file.h foo* foo.o main.o run123 run234 run303 bar.o file.pro foo.c main.h q.c run2 run240 sub % l *(ˆ.) link@ morestuff/ pipe stuff/ % l s*(.) stuff/ sub % l *(p) pipe % l -l *(p) prw-r--r-- 1 pfalstad 0 May 23 18:12 pipe
*(U) matches all files owned by you. To search for all files not owned by you, use *(ˆU):
% l -l *(ˆU) -rw------- 1 subbarao 29 May 23 18:13 sub
This searches for setuid files:
% l -l *(s) -rwsr-xr-x 1 pfalstad 16 May 23 18:12 foo*
This checks for a certain user’s files:
% l -l *(u[subbarao]) -rw------- 1 subbarao 29 May 23 18:13 sub