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