[ prev | next | top ]

2. Filename Generation

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 <xy> 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


[ prev | next | top ]