1 .\" Title: zsh-lovers
2 .\" Author:
3 .\" Generator: DocBook XSL Stylesheets v1.73.2 <http://docbook.sf.net/>
4 .\" Date: 03/12/2009
5 .\" Manual:
6 .\" Source:
7 .\"
8 .TH "ZSH\-LOVERS" "1" "03/12/2009" "" ""
9 .\" disable hyphenation
10 .nh
11 .\" disable justification (adjust text to left margin only)
12 .ad l
13 .SH "NAME"
14 zsh-lovers \- tips, tricks and examples for the Z shell
15 .SH "SYNOPSIS"
16 Just read it\&. ;\-)
17 .sp
18 .SH "OVERVIEW"
19 Whenever we look at the zsh manual we wonder why there are no examples or those simply things in (shell) life\&. The zsh contains many features, but there was no manpage with some examples (like procmailex(5))\&. That\'s why we wrote this manpage\&.
20 .sp
21 Most of the tricks and oneliner come from the mailinglists zsh\-users, zsh\-workers, google, newsgroups and from ourself\&. See section \fBLINKS\fR for details\&.
22 .sp
23 Note: This manpage (zsh\-lovers(1)) is \fBnot\fR an offical part of the Z shell! It\'s just a just for fun \- manpage ;) For comments, bugreports and feedback take a quick look at the section \fBBUGS\fR\&.
24 .sp
25 .SH "SHELL-SCRIPTING"
26 This section provides some examples for often needed shellscript\-stuff\&. Notice that you should not use otherwise most examples won\'t work\&. Parse options in shellscripts\&. Example taken from ZWS by Adam Chodorowski (http://www\&.chodorowski\&.com/projects/zws/):
27 .sp
28 .sp
29 .RS 4
30 .nf
31 parse_options()
32 {
33 o_port=(\-p 9999)
34 o_root=(\-r WWW)
35 o_log=(\-d ZWS\&.log)
36
37 zparseopts \-K \-\- p:=o_port r:=o_root l:=o_log h=o_help
38 if [[ $? != 0 || "$o_help" != "" ]]; then
39 echo Usage: $(basename "$0") "[\-p PORT] [\-r DIRECTORY]"
40 exit 1
41 fi
42
43 port=$o_port[2]
44 root=$o_root[2]
45 log=$o_log[2]
46
47 if [[ $root[1] != \'/\' ]]; then root="$PWD/$root"; fi
48 }
49 # now use the function:
50 parse_options $*
51 .fi
52 .RE
53 .SH "EXAMPLES"
54 Available subsections are \fBAliases\fR, \fBCompletion\fR, \fBUnsorted/Misc examples\fR, \fB(Recursive) Globbing \- Examples\fR, \fBModifiers usage\fR, \fBRedirection\-Examples\fR, \fBZMV\-Examples\fR and \fBModule\-Examples\fR\&.
55 .sp
56 .SS "ALIASES"
57 Suffix aliases are supported in zsh since version 4\&.2\&.0\&. Some examples:
58 .sp
59 .sp
60 .RS 4
61 .nf
62 alias \-s tex=vim
63 alias \-s html=w3m
64 alias \-s org=w3m
65 .fi
66 .RE
67 Now pressing return\-key after entering \fIfoobar\&.tex\fR starts vim with foobar\&.tex\&. Calling a html\-file runs browser w3m\&. \fIwww\&.zsh\&.org\fR and pressing enter starts w3m with argument www\&.zsh\&.org\&. Global aliases can be used anywhere in the command line\&. Example:
68 .sp
69 .sp
70 .RS 4
71 .nf
72 $ alias \-g C=\'| wc \-l\'
73 $ grep alias ~/\&.zsh/* C
74 443
75 .fi
76 .RE
77 Some more or less useful global aliases (choose whether they are useful or not for you on your own):
78 .sp
79 .sp
80 .RS 4
81 .nf
82 alias \-g \&.\&.\&.=\'\&.\&./\&.\&.\'
83 alias \-g \&.\&.\&.\&.=\'\&.\&./\&.\&./\&.\&.\'
84 alias \-g \&.\&.\&.\&.\&.=\'\&.\&./\&.\&./\&.\&./\&.\&.\'
85 alias \-g CA="2>&1 | cat \-A"
86 alias \-g C=\'| wc \-l\'
87 alias \-g D="DISPLAY=:0\&.0"
88 alias \-g DN=/dev/null
89 alias \-g ED="export DISPLAY=:0\&.0"
90 alias \-g EG=\'|& egrep\'
91 alias \-g EH=\'|& head\'
92 alias \-g EL=\'|& less\'
93 alias \-g ELS=\'|& less \-S\'
94 alias \-g ETL=\'|& tail \-20\'
95 alias \-g ET=\'|& tail\'
96 alias \-g F=\' | fmt \-\'
97 alias \-g G=\'| egrep\'
98 alias \-g H=\'| head\'
99 alias \-g HL=\'|& head \-20\'
100 alias \-g Sk="*~(*\&.bz2|*\&.gz|*\&.tgz|*\&.zip|*\&.z)"
101 alias \-g LL="2>&1 | less"
102 alias \-g L="| less"
103 alias \-g LS=\'| less \-S\'
104 alias \-g MM=\'| most\'
105 alias \-g M=\'| more\'
106 alias \-g NE="2> /dev/null"
107 alias \-g NS=\'| sort \-n\'
108 alias \-g NUL="> /dev/null 2>&1"
109 alias \-g PIPE=\'|\'
110 alias \-g R=\' > /c/aaa/tee\&.txt \'
111 alias \-g RNS=\'| sort \-nr\'
112 alias \-g S=\'| sort\'
113 alias \-g TL=\'| tail \-20\'
114 alias \-g T=\'| tail\'
115 alias \-g US=\'| sort \-u\'
116 alias \-g VM=/var/log/messages
117 alias \-g X0G=\'| xargs \-0 egrep\'
118 alias \-g X0=\'| xargs \-0\'
119 alias \-g XG=\'| xargs egrep\'
120 alias \-g X=\'| xargs\'
121 .fi
122 .RE
123 .SS "COMPLETION"
124 See also man 1 zshcompctl zshcompsys zshcompwid\&. zshcompctl is the old style of zsh programmable completion, zshcompsys is the new completion system, zshcompwid are the zsh completion widgets\&.
125 .sp
126 Some functions, like _apt and _dpkg, are very slow\&. You can use a cache in order to proxy the list of results (like the list of available debian packages) Use a cache:
127 .sp
128 .sp
129 .RS 4
130 .nf
131 zstyle \':completion:*\' use\-cache on
132 zstyle \':completion:*\' cache\-path ~/\&.zsh/cache
133 .fi
134 .RE
135 Prevent CVS files/directories from being completed:
136 .sp
137 .sp
138 .RS 4
139 .nf
140 zstyle \':completion:*:(all\-|)files\' ignored\-patterns \'(|*/)CVS\'
141 zstyle \':completion:*:cd:*\' ignored\-patterns \'(*/)#CVS\'
142 .fi
143 .RE
144 Fuzzy matching of completions for when you mistype them:
145 .sp
146 .sp
147 .RS 4
148 .nf
149 zstyle \':completion:*\' completer _complete _match _approximate
150 zstyle \':completion:*:match:*\' original only
151 zstyle \':completion:*:approximate:*\' max\-errors 1 numeric
152 .fi
153 .RE
154 And if you want the number of errors allowed by _approximate to increase with the length of what you have typed so far:
155 .sp
156 .sp
157 .RS 4
158 .nf
159 zstyle \-e \':completion:*:approximate:*\' \e
160 max\-errors \'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)\'
161 .fi
162 .RE
163 Ignore completion functions for commands you don\'t have:
164 .sp
165 .sp
166 .RS 4
167 .nf
168 zstyle \':completion:*:functions\' ignored\-patterns \'_*\'
169 .fi
170 .RE
171 With helper functions like:
172 .sp
173 .sp
174 .RS 4
175 .nf
176 xdvi() { command xdvi ${*:\-*\&.dvi(om[1])} }
177 .fi
178 .RE
179 you can avoid having to complete at all in many cases, but if you do, you might want to fall into menu selection immediately and to have the words sorted by time:
180 .sp
181 .sp
182 .RS 4
183 .nf
184 zstyle \':completion:*:*:xdvi:*\' menu yes select
185 zstyle \':completion:*:*:xdvi:*\' file\-sort time
186 .fi
187 .RE
188 Completing process IDs with menu selection:
189 .sp
190 .sp
191 .RS 4
192 .nf
193 zstyle \':completion:*:*:kill:*\' menu yes select
194 zstyle \':completion:*:kill:*\' force\-list always
195 .fi
196 .RE
197 If you end up using a directory as argument, this will remove the trailing slash (usefull in ln)
198 .sp
199 .sp
200 .RS 4
201 .nf
202 zstyle \':completion:*\' squeeze\-slashes true
203 .fi
204 .RE
205 cd will never select the parent directory (e\&.g\&.: cd \&.\&./<TAB>):
206 .sp
207 .sp
208 .RS 4
209 .nf
210 zstyle \':completion:*:cd:*\' ignore\-parents parent pwd
211 .fi
212 .RE
213 Another method for \fIquick change directories\fR\&. Add this to your ~/\&.zshrc, then just enter \(lqcd \&...\&./dir\(rq
214 .sp
215 .sp
216 .RS 4
217 .nf
218 rationalise\-dot() {
219 if [[ $LBUFFER = *\&.\&. ]]; then
220 LBUFFER+=/\&.\&.
221 else
222 LBUFFER+=\&.
223 fi
224 }
225 zle \-N rationalise\-dot
226 bindkey \&. rationalise\-dot
227 .fi
228 .RE
229 .SS "UNSORTED/MISC examples"
230 Hint: A list of valid glob Qualifiers can be found in zshexpn(1)\&. See \(lqman 1 zshexpn | less \-p\(rq Qualifiers for details\&.
231 .sp
232 .sp
233 .RS 4
234 .nf
235 # Get the names of all files that *don\'t* match a pattern *anywhere* on the
236 # file (and without ``\-L\'\' because its GNUish)
237 $ print \-rl \-\- *(\&.^e{\'grep \-q pattern $REPLY\'})
238 # or
239 $ : *(\&.e{\'grep \-q pattern $REPLY || print \-r \-\- $REPLY\'})
240
241 # random numbers
242 $ echo $[${RANDOM}%1000] # random between 0\-999
243 $ echo $[${RANDOM}%11+10] # random between 10\-20
244 $ echo ${(l:3::0:)${RANDOM}} # N digits long (3 digits)
245
246 # reverse a word
247 $ echo "${(j::)${(@Oa)${(s::):\-hello}}}"
248
249 # Show newest directory
250 $ ls \-ld *(/om[1])
251
252 # random array element
253 $ FILES=( \&.\&.\&./files/* )
254 $ feh $FILES[$RANDOM%$#FILES+1]
255
256 # cat first line in all files in this dir
257 $ for file (*(ND\-\&.)) IFS= read \-re < $file
258
259 # test if a parameter is numeric
260 $ if [[ $1 == <\-> ]] ; then
261 echo numeric
262 else
263 echo non\-numeric
264 fi
265
266 # Show me all the \&.c files for which there doesn\'t exist a \&.o file\&.
267 $ print *\&.c(e_\'[[ ! \-e $REPLY:r\&.o ]]\'_)
268
269 # All files in /var/ that are not owned by root
270 $ ls \-ld /var/*(^u:root)
271
272 # All files for which the owner hat read and execute permissions
273 $ echo *(f:u+rx:)
274
275 # The same, but also others dont have execute permissions
276 $ echo *(f:u+rx,o\-x:)
277
278 # brace expansion \- example
279 $ X=(A B C)
280 $ Y=(+ \-)
281 $ print \-r \-\- $^X\&.$^Y
282 A\&.+ A\&.\- B\&.+ B\&.\- C\&.+ C\&.\-
283
284 # Fetch the newest file containing the string \'fgractg*\&.log\' in the
285 # filename and contains the string \'ORA\-\' in it
286 $ file=(fgractg*\&.log(Nm0om[1]))
287 $ (($#file)) && grep \-l ORA\- $file
288 # without Zsh
289 $ files=$( find \&. \-name \&. \-o \-prune \-name \'fgractg*>log\' \-mtime 0 \-print )
290 > if [ \-n "$files" ]; then
291 > IFS=\'
292 > \'
293 > set \-f
294 > file=$(ls \-td $files | head \-1)
295 > grep \-l ORA\- "$file"
296 > fi
297
298 # keep specified number of child processes running until entire task finished
299 $ zsh \-c \'sleep 1 & sleep 3 & sleep 2& print \-rl \-\- $jobtexts\'
300
301 # Remove zero length and \&.bak files in a directory
302 $ rm \-i *(\&.L0) *\&.bak(\&.)
303
304 # print out files that dont have extensions
305 $ printf \'%s\en\' ^?*\&.*
306 $ printf \'%s\en\' ^?*\&.[^\&.]*(D)
307 $ ls \-d \-\- ^?*\&.*(D)
308
309 # Finding files which does not contain a specific string
310 $ print \-rl file* | comm \-2 \-3 \- <(grep \-l string file*)\'
311 $ for f (file*(N)) grep \-q string $f || print \-r $f\'
312
313 # Show/Check whether a option is set or not\&. It works both with $options as
314 # with $builtins
315 $ echo $options[correct]
316 off
317 $ $options[zle]
318 on
319
320 # Count the number of directories on the stack
321 $ print $((${${(z)${(f)"$(dirs \-v)"}[\-1]}[1]} + 1)) # or
322 $ dirs \-v | awk \'{n=$1}END{print n+1}\'
323
324 # Matching all files which do not have a dot in filename
325 $ ls *~*\&.*(\&.)
326
327 # Show only the ip\-address from ``ifconfig device\'\'
328 # ifconfig from net\-tools (Linux)
329 $ print ${${$(LC_ALL=C /sbin/ifconfig eth0)[7]}:gs/addr://}
330 # ifconfig from 4\&.2BSD {Free,Net,Open}BSD
331 $ print ${$(/sbin/ifconfig tun0)[6]}
332
333 # Ping all the IP addresses in a couple of class C\'s or all hosts
334 # into /etc/hosts
335 $ for i in {1\&.\&.254}; do ping \-c 1 192\&.168\&.13\&.$i; done
336 or
337 $ I=1
338 $ while ( [[ $I \-le 255 ]] ) ; do ping \-1 2 150\&.150\&.150\&.$I; let I++; done
339 or
340 $ for i in $(sed \'s/#\&.*//\' > /etc/hosts | awk \'{print $2}\')
341 : do
342 : echo "Trying $i \&.\&.\&. "
343 : ping \-c 1 $i ;
344 : echo \'=============================\'
345 : done
346
347 # load all available modules at startup
348 $ typeset \-U m
349 $ m=()
350 $ for md ($module_path) m=($m $md/**/*(*e:\'REPLY=${REPLY#$md/}\'::r))
351 $ zmodload \-i $m
352
353 # Rename all files within a directory such that their names get a numeral
354 # prefix in the default sort order\&.
355 $ i=1; for j in *; do mv $j $i\&.$j; ((i++)); done
356 $ i=1; for f in *; do mv $f $(echo $i | \e
357 awk \'{ printf("%03d", $0)}\')\&.$f; ((i++)); done
358 $ integer i=0; for f in *; do mv $f $[i+=1]\&.$f; done
359
360 # Find (and print) all symbolic links without a target within the current
361 # dirtree\&.
362 $ $ file **/*(D@) | fgrep broken
363 $ for i in **/*(D@); [[ \-f $i || \-d $i ]] || echo $i
364 $ echo **/*(@\-^\&./=%p)
365 $ print \-l **/*(\-@)
366
367 # List all plain files that do not have extensions listed in `fignore\'
368 $ ls **/*~*(${~${(j/|/)fignore}})(\&.)
369 # see above, but now omit executables
370 $ ls **/*~*(${~${(j/|/)fignore}})(\&.^*)
371
372 # Print out files that dont have extensions (require *setopt extendedglob*
373 # and *setopt dotglob*)
374 $ printf \'%s\en\' ^?*\&.*
375
376 # List files in reverse order sorted by name
377 $ print \-rl \-\- *(On)
378 or
379 $ print \-rl \-\- *(^on)
380
381 # Synonymic to ``ps ax | awk \'{print $1}\'\'\'
382 $ print \-l /proc/*/cwd(:h:t:s/self//)
383
384 # Get the PID of a process (without ``ps\'\', ``sed\'\', ``pgrep\'\', \&.\&.
385 # (under Linux)
386 $ pid2 () {
387 > local i
388 > for i in /proc/<\->/stat
389 > do
390 > [[ "$(< $i)" = *\e((${(j:|:)~@})\e)* ]] && echo $i:h:t
391 > done
392 > }
393
394 # for X in \'n\' \'o\' \'p\' \'q\' \'r\' \'s\' \'t\' \'u\' \'v\' \'w\' \'x\' \'y\'; do \&.\&.\&.
395 $ for (( i = 36#n; i <= 36#y; i++ )); do
396 > print ${$(([##36]i)):l}
397 > done
398 # or in combination with ``dc\'\'
399 $ print {$((##n))\&.\&.$((##y))}P\e 10P | dc
400 # or with ``eval\'\'
401 $ eval print \'${$(([##36]\'{$((36#n))\&.\&.$((36#y))}\')):l}\'
402
403 # foreach in one line of shell
404 $ for f (*) print \-r \-\- $f
405
406 # copy a directory recursively without data/files
407 $ dirs=(**/*(/))
408 $ cd \-\- $dest_root
409 $ mkdir \-p \-\- $dirs
410 # or without zsh
411 $ find \&. \-type d \-exec env d="$dest_root" \e
412 sh \-c \' exec mkdir \-p \-\- "$d/$1"\' \'{}\' \'{}\' \e;
413
414 # If `foo=23\'\', then print with 10 digit with leading \'0\'\&.
415 $ foo=23
416 $ print ${(r:10::0:)foo}
417
418 # find the name of all the files in their home directory that have
419 # more than 20 characters in their file names
420 print \-rl $HOME/${(l:20::?:)~:\-}*
421
422 # Save arrays
423 $ print \-r \-\- ${(qq)m} > $nameoffile # save it
424 $ eval "m=($(cat \-\- $nameoffile)" # or use
425 $ m=("${(@Q)${(z)"$(cat \-\- $nameoffile)"}}") # to restore it
426
427 # get a "ls \-l" on all the files in the tree that are younger than a
428 # specified age (e\&.g "ls \-l" all the files in the tree that where
429 # modified in the last 2 days)
430 $ ls \-tld **/*(m\-2)
431 # This will give you a listing 1 file perl line (not à la ls \-R)\&.
432 # Think of an easy way to have a "ls \-R" style output with
433 # only files newer than 2 day old\&.
434 $ for d (\&. \&./**/*(/)) {
435 > print \-r \-\- $\'\en\'${d}:
436 > cd $d && {
437 > l=(*(Nm\-2))
438 > (($#l)) && ls \-ltd \-\- $l
439 > cd ~\-
440 > }
441 > }
442 # If you also want directories to be included even if their mtime
443 # is more than 2 days old:
444 $ for d (\&. \&./**/*(/)) {
445 > print \-r \-\- $\'\en\'${d}:
446 > cd $d && {
447 > l=(*(N/,m\-2))
448 > (($#l)) && ls \-ltd \-\- $l
449 > cd ~\-
450 > }
451 > }
452 # And if you want only the directories with mtime < 2 days to be listed:
453 $ for d (\&. \&./**/*(N/m\-2)) {
454 > print \-r \-\- $\'\en\'${d}:
455 > cd $d && {
456 > l=(*(Nm\-2))
457 > (($#l)) && ls \-ltd \-\- $l
458 > cd ~\-
459 > }
460 > }
461
462 # print 42 ``\-\'\'
463 $ echo ${(l:42::\-:)}
464 # or use ``$COLUMS\'\'
465 $ echo ${(l:$COLUMNS::\-:)}
466 # and now with colors (require autoload colors ;colors)
467 $ echo "$bg[red]$fg[black]${(l:42::\-:)}"
468
469 # Redirect STDERR to a command like xless without redirecting STDOUT as well\&.
470 $ foo 2>>(xless)
471 # but this executes the command asynchronously\&. To do it synchronously:
472 $ { { foo 1>&3 } 2>&1 | xless } 3>&1
473
474 # Rename all MP3\-Files from name with spaces\&.mp3 to Name With Spaces\&.mp3
475 $ for i in *\&.mp3; do
476 > mv $i ${${(C)i}:s/Mp3/mp3/}
477 > done
478
479 # Match file names containing only digits and ending with \&.xml (require
480 # *setopt kshglob*)
481 $ ls \-l [0\-9]##\&.xml
482 $ ls \-l <0\->\&.xml
483
484 # Remove all "non txt" files
485 $ rm \&./^*\&.txt
486
487 # Move 200 files from a directory into another
488 $ mv \-\- *([1,200]) /another/Dir
489
490 # Convert images (foo\&.gif => foo\&.png):
491 $ for i in **/*\&.gif; convert $i $i:r\&.png
492
493 # convert a collection of mp3 files to wave or cdr,
494 # e\&.g\&. file\&.wav \-> file\&.mp3)
495 $ for i (\&./*\&.mp3){mpg321 \-\-w \- $i > ${i:r}\&.wav}
496
497 # Download with LaTeX2HTML created Files (for example the ZSH\-Guide):
498 $ for f in http://zsh\&.sunsite\&.dk/Guide/zshguide{,{01\&.\&.08}}\&.html; do
499 > lynx \-source $f >${f:t}
500 > done
501
502 # Move all files in dir1 and dir2 that have line counts greater than 10 to
503 # another directory say "/more10"
504 $ mv dir[12]/**/*\&.cr(\-\&.e{\'((`wc \-l < $REPLY` > 10))\'}) /more10
505
506 # Make with dpkg a master\-list of everyfile that it has installed
507 $ diff <(find / | sort) <(cat /var/lib/dpkg/info/*\&.list | sort)
508
509 # Replace this fucking Escape\-Sequences:
510 $ autoload colors ; colors
511 $ print "$bg[cyan]$fg[blue]You are a idiot" >> /dev/pts/3
512
513 # Get ASCII value of a character
514 $ char=N ; print $((#char))
515
516 # Filename "Erweiterung"
517 # Note: The (N) says to use the nullglob option for this particular
518 # glob pattern\&.
519 $ for i in *\&.o(N); do
520 > rm $i
521 > done
522
523 # Rename files; i\&. e\&. FOO to foo and bar to BAR
524 $ for i in *(\&.); mv $i ${i:l} # `FOO\' to `foo\'
525 $ for i in *(\&.); mv $i ${i:u} # `bar to `BAR\'
526
527 # Show all suid\-files in $PATH
528 $ ls \-latg ${(s\&.:\&.)PATH} | grep \'^\&.\&.\&.s\'
529 # or more complex ;)
530 $ print \-l ${^path}/*(Ns,S)
531 # or show only executables with a user given pattern
532 $ print \-l ${^path}/*vim*(*N)
533
534 # gzip files when containing a certain string
535 $ gzip ${(ps:\e0:)"$(grep \-lZ foobar \&./*\&.txt(\&.))"}
536
537 # A small one\-liner, that reads from stdin and prints to stdout the first
538 # unique line i\&. e\&. does not print lines that have been printed before
539 # (this is similar to the unique command, but unique can only handle
540 # adjacent lines)\&.
541 $ IFS=$\'\en\en\'; print \-rl \-\- ${(Oau)${(Oa)$(cat file;echo \&.)[1,\-2]}}
542
543 # Lists every executable in PATH
544 $ print \-l ${^path}/*(\-*N)
545
546 # Match all \&.c files in all subdirectories, _except_ any SCCS subdirectories?
547 $ ls **/*\&.c~(*/)#SCCS/*
548
549 # List all `README\' \- files case\-insensitive with max\&. one typo
550 $ ls **/*(#ia2)readme
551
552 # case insensitive checking for variables
553 $ if [[ $OSTYPE == (#i)LINUX*(#I) ]]; then
554 > echo "Penguin on board\&."
555 > else
556 > echo "Not a Linux\&."
557 > fi
558 .fi
559 .RE
560 .SS "(Recursive) Globbing \- Examples"
561 A list of valid glob Qualifiers can be found in zshexpn(1)\&. \fBNote:\fR **/ is equivalent to (*/)#! For example:
562 .sp
563 .sp
564 .RS 4
565 .nf
566 $ print (*/)#zsh_us\&.ps
567 zsh\-4\&.2\&.3/Doc/zsh_us\&.ps
568 $ print **/zsh_us\&.ps
569 zsh\-4\&.2\&.3/Doc/zsh_us\&.ps
570 .fi
571 .RE
572 .sp
573 .RS 4
574 .nf
575 # Search for `README\' in all Subdirectories
576 $ ls \-l **/README
577
578 # find directories that contain both "index\&.php" and "index\&.html", or in
579 # general, directories that contain more than one file matching "index\&.*"
580 $ ls **/*(D/e:\'[[ \-e $REPLY/index\&.php && \-e $REPLY/index\&.html ]]\':)
581 # or
582 $ ls **/*(D/e:\'l=($REPLY/index\&.*(N)); (( $#l >= 2 ))\':)
583
584 # Find command to search for directory name instead of basename
585 $ print \-rl /**/*~^*/path(|/*)
586 # or \- without Zsh
587 $ find / | grep \-e /path/ \-e \'/path$\'
588
589 # Print he path of the directories holding the ten biggest C regular files
590 # in the current directory and subdirectories\&.
591 $ print \-rl \-\- **/*\&.c(D\&.OL[1,10]:h) | sort \-u
592
593 # Find files with size == 0 and send a mail
594 $ files=(**/*(ND\&.L0m+0m\-2))
595 > (( $#files > 0 )) && print \-rl \-\- $files | \e
596 mailx \-s "empty files" foo@bar\&.tdl
597
598 # recursive chmod
599 $ chmod 700 **/(\&.) # Only files
600 $ chmod 700 **/(/) # Only directories
601
602 # print out all of the files in that directory in 2 columns
603 $ print \-rC2 \-\- ${1:[\&.\&.\&.]}/*(D:t)
604 # ^\- number ob columns
605 # or \- if you feel concerned about special characters \- use
606 $ list=(${1:[\&.\&.\&.]}/*(ND:t))
607 $ (($#list)) && print \-rC2 \-\- ${(V)list}
608
609 # Search all files in /home/*/*\-mail/ with a setting ``chmod \-s\'\' flag
610 # (recursive, include dotfiles) remove the setgid/setuid flag and print
611 # a message
612 $ chmod \-s /home/*/*\-mail(DNs,S) /home/*/*\-mail/**/*(DNs,S))
613 # or with a small script
614 $ for file (/home/*/*\-mail(DNs,S) /home/*/*\-mail/**/*(DNs,S)) {
615 > print \-r \-\- $file
616 > chmod \-s $file && print \-r fixed $file
617 > }
618 # or use ``zargs\'\' (require autoload zargs) prevent the arg list too
619 # long error
620 $ zargs /home/*/*\-mail(DNs,S) /home/*/*\-mail/**/*(DNs,S)) \-\- chmod \-s
621
622 # List files beginning at `foo23\' upwards (foo23, foo24, foo25, \&.\&.)
623 $ ls \-l foo<23\->
624
625 # get all files that begin with the date strings from June 4 through
626 # June 9 of 2004
627 $ ls \-l 200406{04\&.\&.10}*(N)
628 # or if they are of the form 200406XX (require ``setopt extended_glob\'\'
629 $ ls \-l 200306<4\-10>\&.*
630
631 # remove spaces from filenames
632 $ for a in \&./**/*\e *(Dod); do mv $a ${a:h}/${a:t:gs/ /_}; done
633
634 # Show only all *\&.c and *\&.h \- Files
635 $ ls \-l *\&.(c|h)
636
637 # Show only all *\&.c \- files and ignore `foo\&.c\'
638 $ ls *\&.c~foo\&.c
639
640 # show data to *really* binary format
641 $ zsh \-ec \'while {} {printf %\&.8x $n;repeat 8 \e
642 > {read \-ku0 a printf \e %\&.8d $(([##2]#a))};print;((n+=8))}\' < binary
643
644 # Show only world\-readable files
645 $ ls \-l *(R)
646
647 # List files in the current directory are not writable by the owner
648 $ print \-l ~/*(ND\&.^w)
649
650 # find and delete the files which are older than a given parameter
651 # (seconds/minutes/hours)
652 # deletes all regular file in /Dir that are older than 3 hours
653 $ rm \-f /Dir/**/*(\&.mh+3)
654 # deletes all symlinks in /Dir that are older than 3 minutes
655 $ rm \-f /Dir/**/*(@mm+3)
656 # deletes all non dirs in /Dir that are older than 30 seconds
657 $ rm \-f /Dir/**/*(ms+30^/)
658 # deletes all folders, sub\-folders and files older than one hour
659 $ rm \&./**/*(\&.Dmh+1,\&.DL0)
660 # deletes all files more than 6 hours old
661 $ rm \-f **/*(mh+6)
662 # removes all files but the ten newer ones (delete all but last 10
663 # files in a directory)
664 $ rm \&./*(Om[1,\-11])
665 Note: If you get a arg list too long, you use the builtin rm\&. For
666 example:
667 $ zmodload zsh/files ; rm \-f **/*(mh+6)
668 or use the zargs function:
669 $ autoload zargs ; zargs **/*(mh+6) \-\- rm \-f
670
671 # A User\'s Guide to the Z\-Shell /5\&.9: Filename Generation and Pattern
672 # Matching find all files in all subdirectories, searching recursively,
673 # which have a given name, case insensitive, are at least 50 KB large,
674 # no more than a week old and owned by the root user, and allowing up
675 # to a single error in the spelling of the name\&. In fact, the required
676 # expression looks like this:
677 $ ls **/(#ia1)name(LK+50mw\-1u0)
678
679 # Change the UID from 102 to 666
680 $ chown 666 **/*(u102)
681
682 # List all files which have not been updated since last 10 hours
683 $ print \-rl \-\- *(Dmh+10^/)
684
685 # delete only the oldest file in a directory
686 $ rm \&./*filename*(Om[1])
687
688 # Sort the output from `ls \-l\' by file size
689 $ ls \-fld *(OL)
690
691 # find most recent file in a directory
692 $ setopt dotglob ; print directory/**/*(om[1])
693
694 # Show only empty files which nor `group\' or `world writable\'
695 $ ls *(L0f\&.go\-w\&.)
696
697 # Find \- and list \- the ten newest files in directories and subdirs\&.
698 # (recursive)
699 $ print \-rl \-\- **/*(Dom[1,10])
700
701 # Print only 5 lines by "ls" command (like ``ls \-laS | head \-n 5\'\')\&.
702 $ ls \-fl *(DOL[1,5])
703
704 # Display the 5\-10 last modified files\&.
705 $ print \-rl \-\- /path/to/dir/**/*(D\&.om[5,10])
706
707 # Find all files without a valid owner\&.
708 $ chmod someuser /**/*(D^u:${(j\&.:u:\&.)${(f)"$(</etc/passwd)"}%%:*}:)
709
710 # Find all the empty directories in a tree\&.
711 $ for f in ***/*(/l2); do foo=($f/*(N)); [[ \-z $foo ]] && print $f; done
712 # Note:Since Zsh 4\&.2\&.1 the glob qualifier F indicates a non\-empty directory\&.
713 # Hence *(F) indicates all subdirectories with entries, *(/^F) means all
714 # subdirectories with no entries\&.
715 $ ls \-ld *(/^F)
716
717 # Remove empty directories afterwards\&.
718 $ rmdir \&./**/*(/od) 2> /dev/null
719
720 # Show only files which are owned by group `users\'\&.
721 $ ls \-l *(G[users])
722 .fi
723 .RE
724 .SS "Modifiers usage"
725 Modifiers are a powerful mechanism that let you modify the results returned by parameter, filename and history expansion\&. See zshexpn(1) for details\&.
726 .sp
727 .sp
728 .RS 4
729 .nf
730 # NOTE: Zsh 4\&.3\&.4 needed!
731 $ autoload \-U age
732 # files modified today
733 $ print *(e:age today now:)
734 # files modified since 5 pm
735 $ print *(e\-age 17:00 now\-)
736 # \&.\&.\&. since 5 o\'clock yesterda
737 $ print *(e\-age yesterday,17:00 now\-)
738 # \&.\&.\&. from last Christmas before today
739 $ print *(e\-age 2006/12/25 today\-)
740 # \&.\&.\&. before yesterday
741 $ print *(e\-age 1970/01/01 yesterday\-)
742 # all files modified between the start of those dates
743 $ print *(e:age 2006/10/04 2006/10/09:)
744 # all files modified on that date
745 $ print *(e:age 2006/10/04:)
746 # Supply times\&.
747 $ print *(e\-age 2006/10/04:10:15 2006/10/04:10:45\-)
748
749 # Remove a trailing pathname component, leaving the head\&. This works like
750 # `dirname\'\&.
751 $ echo =ls(:h)
752 /bin
753
754 # Remove all leading pathname components, leaving the tail\&. This works
755 # like `basename\'\&.
756 $ echo =ls(:t)
757 ls
758
759 # Remove the suffix from each file (*\&.sh in this example)
760 $f:e is $f file extension
761 :h \-\-> head (dirname)
762 :t \-\-> tail (basename)
763 :r \-\-> rest (extension removed)
764 $ for f (*\&.sh) mv $f $f:r
765
766 # Remove a filename extension of the form `\&.xxx\', leaving the root name\&.
767 $ echo $PWD
768 /usr/src/linux
769 $ echo $PWD:t
770 linux
771
772 # Remove all but the extension\&.
773 $ foo=23\&.42
774 $ echo $foo
775 23\&.42
776 $ echo $foo:e
777 42
778
779 # Print the new command but do not execute it\&. Only works with history
780 # expansion\&.
781 $ echo =ls(:h)
782 /bin
783 $ !echo:p
784 $ echo =ls(:h)
785
786 # Quote the substituted words, escaping further substitutions\&.
787 $ bar="23\'42"
788 $ echo $bar
789 23\'42
790 $ echo $bar:q
791 23\e\'42
792
793 # Convert the words to all lowercase\&.
794 $ bar=FOOBAR
795 $ echo $bar
796 FOOBAR
797 $ echo $bar:l
798 foobar
799
800 # Convert the words to all uppercase\&.
801 $ bar=foobar
802 $ echo $bar
803 foobar
804 $ echo $bar:u
805 FOOBAR
806
807 # convert 1st char of a word to uppercase
808 $ foo="one two three four"
809 $ print \-r \-\- "${(C)foo}"
810 One Two Three Four
811 .fi
812 .RE
813 .SS "Redirection\-Examples"
814 See zshmisc(1) for more informations (or less ${^fpath}/zmv(N))
815 .sp
816 .sp
817 .RS 4
818 .nf
819 # Append `exit 1\' at the end of all *\&.sh \- files
820 $ echo "exit 1" >> *\&.sh
821
822 # adding files to foobar\&.tar\&.gz
823 $ eval set =(gunzip < foobar\&.tar\&.gz) \'
824 tar rf $1 additional\&.txt &&gzip < $1 > foobar\&.tar\&.gz\'
825
826 # Redirect output to a file AND display on screen
827 $ foobar >&1 > file1 > file2 > \&.\&.
828
829 # pipe single output to multiple inputs
830 $ zcat foobar\&.Z >> (gzip \-9 > file1\&.gz) \e
831 >> (bzip2 \-9 > file1\&.bz2) \e
832 >> (acb \-\-best > file1\&.acb)
833
834 # Append /etc/services at the end of file `foo\' and `bar\'
835 $ cat /etc/services >> foo >> bar
836
837 # Pipe STDERR
838 $ echo An error >&2 2>&1 | sed \-e \'s/A/I/\'
839
840 # send standard output of one process to standard input of several processes
841 # in the pipeline
842 $ setopt multios
843 $ process1 > >(process1) > >(process2)
844
845 # initializing a variable and simultaneously keeping terminal output
846 $ setopt multios
847 $ { a=$(command >&1 >& 3 3 > &\- 2>&1);} 3>&1
848
849 # redirect stderr two times
850 $ setopt multios ; program 2> file2 > file1 2>&1
851
852 # Duplicating stdout and stderr to a logfile
853 $ exec 3>&1 > logfile 2>&2 2>&1 >&3 3>&\-
854
855 # redirect stderr (only) to a file and to orig\&. stderr:
856 $ command 2>&2 2>stderr
857 # redirect stderr and stdout to separate files and both to orig\&. stdout:
858 $ command 2>&1 1>&1 2>stderr 1>stdout
859 # redirect stderr and stdout to separate files and stdout to orig\&. stdout
860 # AND stderr to orig\&. stderr:
861 $ command 2>&2 1>&1 2>stderr 1>stdout
862
863 # More fun with STDERR ;)
864 $ \&./my\-script\&.sh 2> >(grep \-v moron >error\&.log)|process\-output >output\&.log
865 $ echo "Thats STDOUT" >>(sed \'s/stdout/another example/\' > foobar)
866 .fi
867 .RE
868 .SS "ZMV\-Examples (require autoload zmv)"
869 \fBNote:\fR \fI\-n\fR means no execution (just print what would happen)\&. At
870 .sp
871 .sp
872 .RS 4
873 .nf
874 # Remove illegal characters in a fat32 file system\&. Illegal characters are
875 # / : ; * ? " < > |
876 # NOTE: ``\-Q\'\' and (D) is to include hidden files\&.
877 $ unwanted=\'[:;*?\e"<>|]\'
878 $ zmv \-Q "(**/)(*$~unwanted*)(D)" \'$1${2//$~unwanted/}\'
879
880 # Changing part of a filename (i\&. e\&. "file\-hell\&.name" \-> "file\-heaven\&.name")
881 $ zmv \'(*)hell(*)\' \'${1}heaven${2}\'
882 # or
883 $ zmv \'*\' \'$f:s/hell/heaven/\'
884
885 # remove round bracket within filenames
886 # i\&. e\&. foo\-(bar)\&.avi \-> foo\-bar\&.avi
887 $ zmv \'*\' \'${f//[()]/}\'
888
889 # serially all files (foo\&.foo > 1\&.foo, fnord\&.foo > 2\&.foo, \&.\&.)
890 $ autoload zmv
891 $ ls *
892 1\&.c asd\&.foo bla\&.foo fnord\&.foo foo\&.fnord foo\&.foo
893 $ c=1 zmv \'*\&.foo\' \'$((c++))\&.foo\'
894 $ ls *
895 1\&.c 1\&.foo 2\&.foo 3\&.foo 4\&.foo foo\&.fnord
896
897 # Rename "file\&.with\&.many\&.dots\&.txt" by substituting dots (exept for the last
898 # one!) with a space
899 $ touch {1\&.\&.20}\-file\&.with\&.many\&.dots\&.txt
900 $ zmv \'(*\&.*)(\&.*)\' \'${1//\&./ }$2\'
901
902 # Remove the first 4 chars from a filename
903 $ zmv \-n \'*\' \'$f[5,\-1]\' # NOTE: The "5" is NOT a mistake in writing!
904
905 # Rename names of all files under the current Dir to lower case, but keep
906 # dirnames as\-is\&.
907 $ zmv \-Qv \'(**/)(*)(\&.D)\' \'$1${(L)2}\'
908
909 # replace all 4th character, which is "1", with "2" and so on
910 $ autoload \-U zmv
911 $ zmv \'(???)1(???[1\-4]\&.txt)\' \'${1}2${2}\'
912
913 # Remove the first 15 characters from a string
914 $ touch 111111111111111{a\-z}
915 $ autoload zmv
916 $ zmv \'*\' \'$f[16,\-1]\'
917
918 # Replace spaces (any number of them) with a single dash in file names
919 $ autload zmv
920 $ zmv \-n \'(**/)(* *)\' \'$1${2//( #\-## #| ##)/\-}\'
921 # or \- with Bash
922 $ find \&. \-depth \-name \'* *\' \-exec bash \-c \'
923 > shopt \-s extglob
924 > file=$1
925 > dir=${file%/*}
926 > name=${file##*/}
927 > newname=${name//*([ \-]) *([ \-])/\-}
928 > mv \-i \-\- "$file" "$Dir/$newname"\' {} {} \e;
929
930 # Clean up file names and remove special characters
931 $ autoload zmv
932 $ zmv \-n \'(**/)(*)\' \'$1${2//[^A\-Za\-z0\-9\&._]/_}\'
933
934 # Add *\&.py to a bunch of python scripts in a directory (some of them end
935 # in *\&.py and give them all a proper extension
936 $ autoload zmv
937 $ zmv \-n \'(**/)(con*)(#qe,file $REPLY | grep "python script",)\' \'$1$2\&.py\'
938
939 # lowercase all extensions (i\&. e\&. *\&.JPG) incl\&. subfolders
940 $ autoload zmv
941 $ zmv \'(**/)(*)\&.(#i)jpg\' \'$1$2\&.jpg\'
942 # Or \- without Zsh
943 $ find Dir \-name \'*\&.[jJ][pP][gG]\' \-print | while read f
944 > do
945 > case $f in
946 > *\&.jpg) ;
947 > *) mv "$f" "${f%\&.*}\&.jpg" ;
948 > esac
949 > done
950
951 # remove leading zeros from file extension
952 $ autoload zmv
953 $ ls
954 filename\&.001 filename\&.003 filename\&.005 filename\&.007 filename\&.009
955 filename\&.002 filename\&.004 filename\&.006 filename\&.008 filename\&.010
956 $ zmv \'(filename\&.)0##(?*)\' \'$1$2\'
957 $ ls
958 filename\&.1 filename\&.10 filename\&.2 filename\&.3 filename\&.4 filename\&.5 \&.\&.
959
960 # renumber files\&.
961 $ autoload zmv
962 $ ls *
963 foo_10\&.jpg foo_2\&.jpg foo_3\&.jpg foo_4\&.jpg foo_5\&.jpg foo_6\&.jpg \&.\&.
964 $ zmv \-fQ \'foo_(<0\->)\&.jpg(\&.nOn)\' \'foo_$(($1 + 1))\&.jpg\'
965 $ ls *
966 foo_10\&.jpg foo_11\&.jpg foo_3\&.jpg foo_4\&.jpg foo_5\&.jpg \&.\&.\&.
967
968 # adding leading zeros to a filename (1\&.jpg \-> 001\&.jpg, \&.\&.
969 $ autoload zmv
970 $ zmv \'(<1\->)\&.jpg\' \'${(l:3::0:)1}\&.jpg\'
971
972 # See above, but now only files with a filename >= 30 chars
973 $ autoload zmv
974 $ c=1 zmv "${(l:30\-4::?:)}*\&.foo" \'$((c++))\&.foo\'
975
976 # Replace spaces in filenames with a underline
977 $ autoload zmv
978 $ zmv \'* *\' \'$f:gs/ /_\'
979
980 # Change the suffix from *\&.sh to *\&.pl
981 $ autoload zmv
982 $ zmv \-W \'*\&.sh\' \'*\&.pl\'
983
984 # Add a ""\&.txt" extension to all the files within ${HOME}
985 # ``\-\&.\'\' is to only rename regular files or symlinks to regular files,
986 # ``D\'\' is to also rename hidden files (dotfiles))
987 $ autoload zmv
988 $ zmv \-Q \'/home/**/*(D\-\&.)\' \'$f\&.txt\'
989 # Or to only rename files that don\'t have an extension:
990 $ zmv \-Q \'/home/**/^?*\&.*(D\-\&.)\' \'$f\&.txt\'
991
992 # Recursively change filenames with characters ? [ ] / = + < > ; : " , \- *
993 $ autoload zmv
994 $ chars=\'[][?=+<>;",*\-]\'
995 $ zmv \'(**/)(*)\' \'$1${2//$~chars/%}\'
996
997 # Removing single quote from filenames (recursively)
998 $ autoload zmv
999 $ zmv \-Q "(**/)(*\'*)(D)" "\e$1\e${2//\'/}"
1000
1001 # When a new file arrives (named file\&.txt) rename all files in order to
1002 # get (e\&. g\&. file119\&.txt becomes file120\&.txt, file118\&.txt becomes
1003 # file119\&.txt and so on ending with file\&.txt becoming file1\&.txt
1004 $ autoload zmv
1005 $ zmv \-fQ \'file([0\-9]##)\&.txt(On)\' \'file$(($1 + 1))\&.txt\'
1006
1007 # lowercase/uppercase all files/directories
1008 $ autoload zmv
1009 $ zmv \'(*)\' \'${(L)1}\' # lowercase
1010 $ zmv \'(*)\' \'${(U)1}\' # uppercase
1011
1012 # Remove the suffix *\&.c from all C\-Files
1013 $ autoload zmv
1014 $ zmv \'(*)\&.c\' \'$1\'
1015
1016 # Uppercase only the first letter of all *\&.mp3 \- files
1017 $ autoload zmv
1018 $ zmv \'([a\-z])(*)\&.mp3\' \'${(C)1}$2\&.mp3\'
1019
1020 # Copy the target `README\' in same directory as each `Makefile\'
1021 $ autoload zmv
1022 $ zmv \-C \'(**/)Makefile\' \'${1}README\'
1023
1024 # Removing single quote from filenames (recursively)
1025 $ autoload zmv
1026 $ zmv \-Q "(**/)(*\'*)(D)" "\e$1\e${2//\'/}"
1027
1028 # Rename pic1\&.jpg, pic2\&.jpg, \&.\&. to pic0001\&.jpg, pic0002\&.jpg, \&.\&.
1029 $ autoload zmv
1030 $ zmv \'pic(*)\&.jpg\' \'pic${(l:4::0:)1}\&.jpg\'
1031 $ zmv \'(**/)pic(*)\&.jpg\' \'$1/pic${(l:4::0:)2}\&.jpg\' # recursively
1032 .fi
1033 .RE
1034 .SS "Module\-Examples"
1035 Please read zshmodules(1) first!
1036 .sp
1037 .sp
1038 .it 1 an-trap
1039 .nr an-no-space-flag 1
1040 .nr an-break-flag 1
1041 .br
1042 zsh/pcre (require zmodload zsh/pcre)
1043 .RS
1044 .sp
1045 .RS 4
1046 .nf
1047 # Copy files of a certain period (date indicated in the filenames)
1048 $ zmodload zsh/pcre
1049 $ ls \-d \-\- *(e:\'[[ $REPLY \-pcre\-match pcre\-regexp ]]\':)
1050 # or
1051 $ m() { [[ $1 \-pcre\-match pcre\-regexp ]] }
1052 $ ls \-d \-\- *(+m)
1053 .fi
1054 .RE
1055 .RE
1056 .sp
1057 .it 1 an-trap
1058 .nr an-no-space-flag 1
1059 .nr an-break-flag 1
1060 .br
1061 zsh/clone (require zmodload zsh/clone)
1062 .RS
1063 .sp
1064 .RS 4
1065 .nf
1066 # Creates a forked instance of the current shell ($! is set to zero) and
1067 # execute ``command\'\' on /dev/tty8 (for this example)\&.
1068 $ zmodload zsh/clone
1069 $ clone /dev/tty8 && (($! == 0)) && exec command
1070 .fi
1071 .RE
1072 .RE
1073 .sp
1074 .it 1 an-trap
1075 .nr an-no-space-flag 1
1076 .nr an-break-flag 1
1077 .br
1078 zsh/datetime (require zmodload zsh/datetime)
1079 .RS
1080 .sp
1081 .RS 4
1082 .nf
1083 $ zmodload zsh/datetime
1084 $ alias datereplacement=\'strftime "%Y\-%m\-%d" $EPOCHSECONDS\'
1085 $ export DATE=`datereplacement`
1086 $ echo $DATE
1087
1088 # strip date from filename
1089 $ $ zmodload zsh/datetime
1090 $ setopt extendedglob
1091 $ touch aaa_bbb_20041212_c\&.dat eee_fff_20051019_g\&.dat
1092 $ strftime \-s pattern \e
1093 \'???_???_<0\-%Y%m%d>_?\&.dat\' $((EPOCHSECONDS \- 365 * 24 * 60 * 60 / 2))
1094 $ print \-rl \-\- $~pattern
1095 aaa_bbb_20041212_c\&.dat
1096 $ print \-rl \-\- $pattern
1097 ???_???_<0\-20050815>_?\&.dat
1098
1099 # Search files size == 0, to be based on the file name containing a date
1100 # rather than the "last modified" date of the file
1101 $ zmodload \-i zsh/datetime
1102 $ strftime \-s file "abc_de_%m%d%Y\&.dat" $((EPOCHSECONDS \- 24 * 60 * 60 ))
1103 $ files=(**/$file(N\&.L0))
1104 $ (( $#files > 0 )) && print \-rl \-\- $files | \e
1105 mailx \-s "empty files" foo@bar\&.tdl
1106 .fi
1107 .RE
1108 .RE
1109 .sp
1110 .it 1 an-trap
1111 .nr an-no-space-flag 1
1112 .nr an-break-flag 1
1113 .br
1114 zsh/stat (require zmodload zsh/stat)
1115 .RS
1116 .sp
1117 .RS 4
1118 .nf
1119 # test if a symbolic link links to a certain file
1120 $ zmodload \-i zsh/stat
1121 $ ! stat \-LH s foo\&.ln || [[ $s[link] != "foo\&.exe" ]] || ln \-sf foo\&.exe foo\&.ln
1122
1123 # comparing file dates
1124 $ zmodload zsh/stat
1125 $ file1=foo
1126 $ file2=bar
1127 $ touch bar & sleep 5 & touch foo
1128 $ echo $file1 is $(($(stat +mtime $file2) \- \e
1129 $(stat +mtime $file1))) seconds older than $file2\&.
1130 bar is 5 seconds older than foo
1131
1132 # list the files of a disk smaller than some other file
1133 $ zmodload zsh/stat
1134 $ stat \-A max +size some\-other\-file
1135 $ print \-rl \&./**/*(D\&.L\-$max)
1136
1137 # List the top 100 biggest files in a disk
1138 $ zmodload zsh/stat
1139 $ ls \-fld \&./**/*(d`stat +device \&.`OL[1,100])
1140
1141 # Get only the user name and the file names from (like
1142 # ls \-l * | awk \'{print $3" " $8}\')
1143 $ zmodload zsh/stat
1144 $ for file; do
1145 > stat \-sA user +uid \-\- "$file" &&
1146 > print \-r \-\- "$user" "$file"
1147 > done
1148
1149 # get the difference between actual bytes of file and allocated bytes of file
1150 $ zmodload zsh/stat
1151 $ print $(($(stat +block \-\- file) * 512 \- $(stat +size \-\- file)))
1152
1153 # Find largest file
1154 # ``D\'\' : to include dot files (d lowercase is for device)
1155 # ``O\'\' : reverse Ordered (o lowercase for non\-reverse order)
1156 # ``L\'\' : by file Length (l is for number of links)
1157 # ``[1]\'\': return only first one
1158 $ zmodload zsh/stat
1159 $ stat +size \&./*(DOL[1])
1160
1161 # file size in bytes
1162 $ zmodload zsh/stat
1163 $ stat \-L +size ~/\&.zshrc
1164 4707
1165
1166 # Delete files in a directory that hasn\'t been accessed in the last ten days
1167 # and send ONE mail to the owner of the files informing him/her of the files\'
1168 # deletion\&.
1169 $ zmodload zsh/stat zsh/files
1170 $ typeset \-A f; f=()
1171 $ rm \-f /path/**/*(\&.a+10e{\'stat \-sA u +uidr $REPLY; f[$u]="$f[$u]$REPLY"\'})
1172 $ for user (${(k)f}) {print \-rn $f[$user]|mailx \-s "\&.\&.\&." $user}
1173
1174 # Get a "ls \-l" on all the files in the tree that are younger than a
1175 # specified age
1176 $ zmodload zsh/stat
1177 $ for d (\&. \&./**/*(N/m\-2))
1178 > print \-r \-\- $\'\en\'$d: && cd $d && {
1179 > for f (*(Nm\-2om))
1180 > stat \-F \'%b %d %H:%M\' \-LsAs \-\- $f &&
1181 > print \-r \-\- $s[3] ${(l:4:)s[4]} ${(l:8:)s[5]} \e
1182 > ${(l:8:)s[6]} ${(l:8:)s[8]} $s[10] $f ${s[14]:+\-> $s[14]}
1183 > cd ~\-
1184 > }
1185
1186 # get file creation date
1187 $ zmodload zsh/stat
1188 $ stat \-F \'%d %m %Y\' +mtime ~/\&.zshrc
1189 30 06 2004
1190 $ stat \-F \'%D\' +mtime ~/\&.zshrc
1191 06/30/04
1192 .fi
1193 .RE
1194 .RE
1195 .sp
1196 .it 1 an-trap
1197 .nr an-no-space-flag 1
1198 .nr an-break-flag 1
1199 .br
1200 zsh/files (require zmodload zsh/files)
1201 .RS
1202 .sp
1203 .RS 4
1204 .nf
1205 # search a directory for files containing a certain string then copy those
1206 # files to another directory\&.
1207 $ zmodload zsh/files
1208 $ IFS=$\'\e0\'
1209 $ cp $(grep \-lZr foobar \&.) otherdirectory
1210 .fi
1211 .RE
1212 .RE
1213 .sp
1214 .it 1 an-trap
1215 .nr an-no-space-flag 1
1216 .nr an-break-flag 1
1217 .br
1218 zsh/mapfile (require zmodload zsh/mapfile)
1219 .RS
1220 .sp
1221 .RS 4
1222 .nf
1223 # grepping for two patterns
1224 $ zmodload zsh/mapfile
1225 $ pattern1="foo"
1226 $ pattern2="bar foo"
1227 $ print \-l \&./**/*(DN\&.e{\'z=$mapfile[$REPLY] && [[ $z = *$pattern1* && \e
1228 $z = *$pattern2* ]]\'})
1229 # or a solution in combination with zsh/pcre
1230 $ zmodload \-i zsh/mapfile zsh/pcre
1231 $ pattern1="foo"
1232 $ pattern2="bar foo"
1233 $ pcre_compile "(?s)(?=\&.*?$pattern1)\&.*?$pattern2"
1234 $ pcre_study
1235 $ print \-l \&./**/*(DN\&.e{\'pcre_match $mapfile[$REPLY]\'})
1236
1237 # equivalent for ``less /etc/passwd | grep \-v root\'\'
1238 $ zmodload zsh/mapfile
1239 $ IFS=$\'\en\en\'
1240 $ print \-rl \-\- ${${=mapfile[/etc/passwd]}:#*root*}
1241 # or \- for case insensitive
1242 $ setopt extendedglob
1243 $ print \-rl \-\- ${${=mapfile[/etc/passwd]}:#*(#i)root*}
1244
1245 # If a XML\-file contains stuff like ``<TAGA/>\'\' and ``<TAGB/>\'\', number
1246 # this empty tags (ones ending in \'/>\') so if encountered in the same
1247 # order, the preceeding tags would become ``<TAGA/>1</TAGA>\'\' and
1248 # ``<TAGB/>2</TAGB>\'\'
1249 $ zmodload zsh/mapfile
1250 $ cnt=0
1251 $ apfile[data\&.xml\&.new]=${(S)mapfile[data\&.xml]//\e
1252 > (#im)<TAGA>*<\e/TAGA>/<TAGA>$((++cnt))<\e/TAGA>}
1253
1254 # removing all files in users Maildir/new that contain ``filename="gone\&.src\'\'
1255 $ zmodload zsh/{files,mapfile}
1256 $ rm \-f /u1/??/*/Maildir/new/100*(\&.e{\'[[ $mapfile[$REPLY] == \e
1257 *filename=\e"gone\&.scr\e"* ]]\'})
1258
1259 # Grep out the Title from a postscript file and append that value to the
1260 # end of the filename
1261 $ autoload \-U zmv
1262 $ zmodload zsh/mapfile
1263 $ zmv \'(*)\&.ps\' \'$1\-${${${mapfile[$f]##*%%Title: }%% *}//[^a\-zA\-Z0\-9_]/}\&.ps\'
1264 .fi
1265 .RE
1266 .RE
1267 .sp
1268 .it 1 an-trap
1269 .nr an-no-space-flag 1
1270 .nr an-break-flag 1
1271 .br
1272 zsh/mathfunc (require zmodload zsh/mathfunc)
1273 .RS
1274 .sp
1275 .RS 4
1276 .nf
1277 $ zmodload zsh/mathfunc
1278 $ echo $(( sin(1/4\&.0)**2 + cos(1/4\&.0)**2 \- 1 ))
1279 \-1\&.1102230246251565e\-16
1280 $ echo $(( pi = 4\&.0 * atan(1\&.0) ))
1281 3\&.1415926535897931
1282 $ echo $(( f = sin(0\&.3) ))
1283 0\&.29552020666133955
1284 $ print $((1e12 * rand48()))
1285 847909677310\&.23413
1286 $ print $(( rand48(seed) ))
1287 0\&.01043488334700271
1288 .fi
1289 .RE
1290 .RE
1291 .sp
1292 .it 1 an-trap
1293 .nr an-no-space-flag 1
1294 .nr an-break-flag 1
1295 .br
1296 zsh/termcap (require zmodload zsh/termcap)
1297 .RS
1298 .sp
1299 .RS 4
1300 .nf
1301 $ zmodload \-ab zsh/termcap echotc
1302 $ GREEN=`echotc AF 2`
1303 $ YELLOW=`echotc AF 3`
1304 $ RED=`echotc AF 1`
1305 $ BRIGHTRED=`echotc md ; echotc AF 1`
1306 $ print \-l ${GREEN}green ${YELLOW}yellow ${RED}red ${BRIGHTRED}brightred
1307 .fi
1308 .RE
1309 .RE
1310 .sp
1311 .it 1 an-trap
1312 .nr an-no-space-flag 1
1313 .nr an-break-flag 1
1314 .br
1315 zsh/zpty (require zmodload zsh/zpty)
1316 .RS
1317 .sp
1318 .RS 4
1319 .nf
1320 $ zmodload zsh/zpty
1321 $ zpty PW passwd $1
1322 $ zpty PW passwd $1
1323 # ``\-r\'\': read the output of the command name\&.
1324 # ``z\'\' : Parameter
1325 $ zpty \-r PW z \'*password:\'
1326 # send the to command name the given strings as input
1327 $ zpty \-w PW $2
1328 $ zpty \-r PW z \'*password:\'
1329 $ zpty \-w PW $2
1330 # The second form, with the \-d option, is used to delete commands
1331 # previously started, by supplying a list of their names\&. If no names
1332 # are given, all commands are deleted\&. Deleting a command causes the HUP
1333 # signal to be sent to the corresponding process\&.
1334 $ zpty \-d PW
1335 .fi
1336 .RE
1337 .RE
1338 .sp
1339 .it 1 an-trap
1340 .nr an-no-space-flag 1
1341 .nr an-break-flag 1
1342 .br
1343 zsh/net/socket (require zmodload zsh/net/socket)
1344 .RS
1345 .sp
1346 .RS 4
1347 .nf
1348 # ``\-l\'\': open a socket listening on filename
1349 # ``\-d\'\': argument will be taken as the target file descriptor for the
1350 # connection
1351 # ``3\'\' : file descriptor\&. See ``A User\'s Guide to the Z\-Shell\'\'
1352 # (3\&.7\&.2: File descriptors)
1353 $ zmodload zsh/net/socket
1354 $ zsocket \-l \-d 3
1355 # ``\-a\'\': accept an incoming connection to the socket
1356 $ zsocket \-a \-d 4 3
1357 $ zsocket \-a \-d 5 3 # accept a connection
1358 $ echo foobar >&4
1359 $ echo barfoo >&5
1360 $ 4>&\- 5>&\- 3>&
1361 .fi
1362 .RE
1363 .RE
1364 .sp
1365 .it 1 an-trap
1366 .nr an-no-space-flag 1
1367 .nr an-break-flag 1
1368 .br
1369 zsh/zftp (require zmodload zsh/zftp)
1370 .RS
1371 .sp
1372 .RS 4
1373 .nf
1374 $ autoload \-U zfinit
1375 $ zfinit
1376 $ zfparams www\&.example\&.invalid myuserid mypassword
1377 $ zfopen
1378 $ zfcd tips
1379 $ zfls \-l zshtips\&.html
1380 $ zfput zshtips\&.html
1381 $ zfls \-l zshtips\&.html
1382
1383 # Automatically transfer files using FTP with error checking
1384 $ autoload \-U zfinit ; zfinit
1385 $ zftp open host\&.name\&.invalid user passwd || exit
1386 $ zftp get /remote/file > /local/file; r=$?
1387 $ zftp close && exit r
1388
1389 # compress and ftp on the fly
1390 $ autoload \-U zfinit ; zfinit
1391 $ zftp open host\&.name\&.invalid user password
1392 $ zftp get $file | bzip2 > ${file}\&.bz2
1393 $ zftp close
1394
1395 # Recursice ``get\'\'
1396 $ autoload \-U zfinit ; zfinit
1397 $ zfanon cr\&.yp\&.to
1398 $ zfcd daemontools
1399 $ for file in `zfls` ; do
1400 > zfget $file
1401 $ done
1402 $ zfclose
1403
1404 # Upload all regular files in $HOME/foobar (recursive) that are newer than
1405 # two hours to ftp\&.foobar\&.invalid/path/to/upload
1406 $ autoload \-U zfinit ; zfinit
1407 $ zfopen ftp\&.foobar\&.invalid/path/to/upload
1408 $ cd $HOME/foobar
1409 $ zfput \-r **/*(\&.mh\-2)
1410 $ zfclose
1411
1412 # long list of files on a ftp
1413 $ autoload \-U zfinit ; zfinit
1414 $ zfopen some\-host
1415 $ zfcd /some/remote/Dir
1416 $ cd /some/local/Dir
1417 # If the list\&.txt is located on the remote host, change to
1418 # zfget ${(f)"$(zftp get /path/to/remote/list\&.txt)"}
1419 $ zfget ${(f)"$(cat list\&.txt)"}
1420 $ zfclose
1421 .fi
1422 .RE
1423 .RE
1424 .sp
1425 .it 1 an-trap
1426 .nr an-no-space-flag 1
1427 .nr an-break-flag 1
1428 .br
1429 zsh/zselect (require zmodload zsh/zselect)
1430 .RS
1431 .sp
1432 .RS 4
1433 .nf
1434 # It\'s similar to
1435 ,\-\-\-\-
1436 | $ sg=$(stty \-g)
1437 | $ stty \-icanon min 0 time 50
1438 | $ read yesno
1439 | $ stty "$sg"
1440 | $ case "$yesno" in
1441 | > yes) command1;;
1442 | > *) command2;;
1443 | > esac
1444 `\-\-\-\-
1445 $ zmodload zsh/zselect
1446 $ if zselect \-t 500 \-r 0 && read yesno && [ yes = "$yesno" ]; then
1447 > command1
1448 > else
1449 > command1
1450 > fi
1451 .fi
1452 .RE
1453 .RE
1454 .SH "OPTIONS"
1455 .SS "Navigation options"
1456 \fBauto_cd\fR (allow one to change to a directory by entering it as a command)\&. \fBauto_pushd\fR (automatically append dirs to the push/pop list) pushd_ignore_dups (and don\'t duplicate them)\&.
1457 .sp
1458 .SS "Misc"
1459 \fBno_hup\fR (don\'t send HUP signal to background jobs when exiting ZSH)\&. \fBprint_exit_value\fR (show a message with the exit code when a command returns with a non\-zero exit code)
1460 .sp
1461 .sp
1462 .it 1 an-trap
1463 .nr an-no-space-flag 1
1464 .nr an-break-flag 1
1465 .br
1466 History options
1467 .RS
1468 \fBhist_verify\fR (let the user edit the command line after history expansion (e\&.g\&. !ls) instead of immediately running it) Use the same history file for all sessions : \fBsetopt SHARE_HISTORY\fR
1469 .sp
1470 .RE
1471 .sp
1472 .it 1 an-trap
1473 .nr an-no-space-flag 1
1474 .nr an-break-flag 1
1475 .br
1476 Privacy / Security
1477 .RS
1478 \fBno_clobber\fR (or set \-C; prevent \fI>\fR redirection from truncating the given file if it already exists)
1479 .sp
1480 .RE
1481 .sp
1482 .it 1 an-trap
1483 .nr an-no-space-flag 1
1484 .nr an-break-flag 1
1485 .br
1486 Spelling correction
1487 .RS
1488 \fBcorrect\fR (automatically correct the spelling of commands)\&. \fBcorrect_all\fR (automatically correct the spelling of each word on the command line) \fBdvorak\fR (dvorak layout)
1489 .sp
1490 .RE
1491 .SH "UNSORTED/MISC"
1492 Mailpath: simple multiple mailpath:
1493 .sp
1494 .sp
1495 .RS 4
1496 .nf
1497 mailpath=($HOME/Mail/mbox\'?new mail in mbox\'
1498 $HOME/Mail/tux\&.u\-strasbg\'?new mail in tux\'
1499 $HOME/Mail/lilo\'?new mail in lilo\'
1500 $HOME/Mail/ldap\-fr\'?new mail in ldap\-fr\')
1501 .fi
1502 .RE
1503 Mailpath: dynamic mailpath:
1504 .sp
1505 .sp
1506 .RS 4
1507 .nf
1508 typeset \-a mailpath
1509 for i in ~/Mail/Lists/*(\&.); do
1510 mailpath[$#mailpath+1]="${i}?You have new mail in ${i:t}\&."
1511 done
1512 .fi
1513 .RE
1514 Avoid globbing on special commands:
1515 .sp
1516 .sp
1517 .RS 4
1518 .nf
1519 for com in alias expr find mattrib mcopy mdir mdel which;
1520 alias $com="noglob $com"
1521 .fi
1522 .RE
1523 For migrating your bashprompt to zsh use the script bash2zshprompt located in the zsh source distribution under \fIMisc\fR\&.
1524 .sp
1525 For migration from (t)csh to zsh use the c2z tool that converts csh aliases and environment and shell variables to zsh\&. It does this by running csh, and having csh report on aliases and variables\&. The script then converts these to zsh startup files\&. It has some issues and usage information that are documented at the top of this script\&.
1526 .sp
1527 Here are functions to set the title and hardstatus of an \fBXTerm\fR or of \fBGNU Screen\fR to \fIzsh\fR and the current directory, respectively, when the prompt is displayed, and to the command name and rest of the command line, respectively, when a command is executed:
1528 .sp
1529 .sp
1530 .RS 4
1531 .nf
1532 function title {
1533 if [[ $TERM == "screen" ]]; then
1534 # Use these two for GNU Screen:
1535 print \-nR $\' 33k\'$1$\' 33\'\e
1536 print \-nR $\' 33]0;\'$2$\'\'
1537 elif [[ $TERM == "xterm" || $TERM == "rxvt" ]]; then
1538 # Use this one instead for XTerms:
1539 print \-nR $\' 33]0;\'$*$\'\'
1540 fi
1541 }
1542 function precmd { title zsh "$PWD" }
1543 function preexec {
1544 emulate \-L zsh
1545 local \-a cmd; cmd=(${(z)1})
1546 title $cmd[1]:t "$cmd[2,\-1]"
1547 }
1548 .fi
1549 .RE
1550 Put the following line into your ~/\&.screenrc to see this fancy hardstatus:
1551 .sp
1552 .sp
1553 .RS 4
1554 .nf
1555 caption always "%3n %t%? (%u)%?%?: %h%?"
1556 .fi
1557 .RE
1558 Special variables which are assigned:
1559 .sp
1560 .sp
1561 .RS 4
1562 .nf
1563 $LINENO $RANDOM $SECONDS $COLUMNS $HISTCHARS $UID
1564 $EUID $GID $EGID $USERNAME $fignore $mailpath $cdpath
1565 .fi
1566 .RE
1567 .SH "LINKS"
1568 .PP
1569 Primary site
1570 .RS 4
1571
1572 \fBhttp://www\&.zsh\&.org/\fR
1573 .RE
1574 .PP
1575 Project\-page
1576 .RS 4
1577
1578 \fBhttp://sourceforge\&.net/projects/zsh/\fR
1579 .RE
1580 .PP
1581 Z shell page at sunsite\&.dk
1582 .RS 4
1583
1584 \fBhttp://zsh\&.sunsite\&.dk/\fR
1585 .RE
1586 .PP
1587 From Bash to Z Shell: Conquering the Command Line \- the book
1588 .RS 4
1589
1590 \fBhttp://www\&.bash2zsh\&.com/\fR
1591 .RE
1592 .PP
1593 "Zsh \- die magische Shell" (german book about Zsh) by Sven Guckes and Julius Plenz
1594 .RS 4
1595
1596 \fBhttp://zshbuch\&.org/\fR
1597 .RE
1598 .PP
1599 Mailinglistarchive
1600 .RS 4
1601
1602 \fBhttp://www\&.zsh\&.org/mla/\fR
1603 .RE
1604 .PP
1605 ZSH\-FAQ
1606 .RS 4
1607
1608 \fBhttp://zsh\&.dotsrc\&.org/FAQ/\fR
1609 .RE
1610 .PP
1611 Userguide
1612 .RS 4
1613
1614 \fBhttp://zsh\&.sunsite\&.dk/Guide/\fR
1615 .RE
1616 .PP
1617 ZSH\-Wiki
1618 .RS 4
1619
1620 \fBhttp://zshwiki\&.org/home/\fR
1621 .RE
1622 .PP
1623 A short introduction from BYU
1624 .RS 4
1625
1626 \fBhttp://docs\&.cs\&.byu\&.edu/linux/advanced/zsh\&.html\fR
1627 .RE
1628 .PP
1629 Mouse\-Support ;)
1630 .RS 4
1631
1632 \fBhttp://stchaz\&.free\&.fr/mouse\&.zsh\fR
1633 .RE
1634 .PP
1635 Curtains up: introducing the Z shell
1636 .RS 4
1637
1638 \fBhttp://www\-128\&.ibm\&.com/developerworks/linux/library/l\-z\&.html?dwzone=linux\fR
1639 .RE
1640 .PP
1641 ZSH\-Liebhaberseite (german)
1642 .RS 4
1643
1644 \fBhttp://michael\-prokop\&.at/computer/tools_zsh_liebhaber\&.html\fR
1645 .RE
1646 .PP
1647 ZSH\-Seite von Michael Prokop (german)
1648 .RS 4
1649
1650 \fBhttp://michael\-prokop\&.at/computer/tools_zsh\&.html\fR
1651 .RE
1652 .PP
1653 ZSH Prompt introduction
1654 .RS 4
1655
1656 \fBhttp://aperiodic\&.net/phil/prompt/\fR
1657 .RE
1658 .PP
1659 Adam\'s ZSH page
1660 .RS 4
1661
1662 \fBhttp://www\&.adamspiers\&.org/computing/zsh/\fR
1663 .RE
1664 .PP
1665 Zzappers Best of ZSH Tips
1666 .RS 4
1667
1668 \fBhttp://www\&.rayninfo\&.co\&.uk/tips/zshtips\&.html\fR
1669 .RE
1670 .PP
1671 Zsh Webpage by Christian Schneider
1672 .RS 4
1673
1674 \fBhttp://www\&.strcat\&.de/zsh/\fR
1675 .RE
1676 .PP
1677 The zsh\-lovers webpage
1678 .RS 4
1679
1680 \fBhttp://grml\&.org/zsh/\fR
1681 .RE
1682 .PP
1683 IRC channel
1684 .RS 4
1685
1686 \fB#zsh at irc\&.freenode\&.org\fR
1687 .RE
1688 .PP
1689 The Z shell reference\-card (included in the zsh\-lovers debian\-package)
1690 .RS 4
1691
1692 \fBhttp://www\&.bash2zsh\&.com/zsh_refcard/refcard\&.pdf\fR
1693 .RE
1694 .SH "AUTHORS"
1695 This manpage was written by Michael Prokop, Christian \fIstrcat\fR Schneider and Matthias Kopfermann\&. But many ideas have been taken from zsh\-geeks e\&.g\&. from the zsh\-mailinglists (zsh\-users and zsh\-workers), google, newsgroups and the zsh\-Wiki\&. Thanks for your cool and incredible tips\&. We learned much from you!
1696 .sp
1697 In alphabetic order:
1698 .sp
1699 .sp
1700 .RS 4
1701 .nf
1702 Andrew \'zefram\' Main \- http://www\&.fysh\&.org/~zefram/
1703 Barton E\&. Schaefer \- http://www\&.well\&.com/user/barts/
1704 Matthias Kopfermann \- http://www\&.infodrom\&.north\&.de/~matthi/
1705 Oliver Kiddle \- http://people\&.freenet\&.de/opk/
1706 Paul Falstad \- http://www\&.falstad\&.com/
1707 Peter Stephenson \- http://homepage\&.ntlworld\&.com/p\&.w\&.stephenson/
1708 Richard Coleman
1709 Stephane Chazelas \- http://stephane\&.chazelas\&.free\&.fr/
1710 Sven Guckes \- http://www\&.guckes\&.net/
1711 Sven Wischnowsky \- http://w9y\&.de/zsh/zshrc
1712 .fi
1713 .RE
1714 .SH "SEE ALSO"
1715 Manpages of zsh:
1716 .sp
1717 .sp
1718 .RS 4
1719 .nf
1720 zsh Zsh overview
1721 zshall Tthe Z shell meta\-man page
1722 zshbuiltins Zsh built\-in commands
1723 zshcalsys zsh calendar system
1724 zshcompctl zsh programmable completion
1725 zshcompsys Zsh completion system
1726 zshcompwid Zsh completion widgets
1727 zshcontrib User contributions to zsh
1728 zshexpn Zsh expansion and substitution
1729 zshmisc Anything not fitting into the other sections
1730 zshmodules Zsh loadable modules
1731 zshoptions Zsh options
1732 zshparam Zsh parameters
1733 zshroadmap Informal introduction to the zsh manual
1734 zshtcpsys Zsh tcp system
1735 zshzle Zsh command line editing
1736 zshzftpsys Zsh built\-in FTP client
1737 zshall Meta\-man page containing all of the above
1738 .fi
1739 .RE
1740 Note: especially \fIman zshcontrib\fR covers very useful topics! Book: \fBFrom Bash to Z Shell\fR by Oliver Kiddle, Jerry Peck and Peter Stephenson\&. \fBISBN: 1590593766\fR\&. \- \fBbash2zsh\&.com\fR Also take a look at the section \fBLINKS\fR in this manpage\&.
1741 .sp
1742 .SH "BUGS"
1743 Probably\&. This manpage might be never complete\&. So please report bugs, feedback and suggestions to <zsh\-lovers@michael\-prokop\&.at>\&. Thank you!
1744 .sp
1745 .SH "COPYRIGHT"
1746 Copyright (C) Michael Prokop, Christian Schneider and Matthias Kopfermann\&.
1747 .sp
1748 .SH "NOTES"
1749 .IP " 1." 4
1750 zsh-lovers@michael-prokop.at
1751 .RS 4
1752 \%mailto:zsh-lovers@michael-prokop.at
1753 .RE
|