3 .\" Author: [see the "AUTHORS" section]
4 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
10 .TH "ZSH\-LOVERS" "1" "04/03/2014" "\ \&" "\ \&"
11 .\" -----------------------------------------------------------------
12 .\" * Define some portability stuff
13 .\" -----------------------------------------------------------------
14 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15 .\" http://bugs.debian.org/507673
16 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
17 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 .\" -----------------------------------------------------------------
21 .\" * set default formatting
22 .\" -----------------------------------------------------------------
23 .\" disable hyphenation
25 .\" disable justification (adjust text to left margin only)
27 .\" -----------------------------------------------------------------
28 .\" * MAIN CONTENT STARTS HERE *
29 .\" -----------------------------------------------------------------
31 zsh-lovers \- tips, tricks and examples for the Z shell
37 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\(cqs why we wrote this manpage\&.
39 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\&.
41 Note: This manpage (zsh\-lovers(1)) is \fBnot\fR an offical part of the Z shell! It\(cqs just a just for fun \- manpage ;) For comments, bugreports and feedback take a quick look at the section \fBBUGS\fR\&.
44 This section provides some examples for often needed shellscript\-stuff\&. Notice that you should not use otherwise most examples won\(cqt work\&. Parse options in shellscripts\&. Example taken from ZWS by Adam Chodorowski (http://www\&.chodorowski\&.com/projects/zws/):
56 zparseopts \-K \-\- p:=o_port r:=o_root l:=o_log h=o_help
57 if [[ $? != 0 || "$o_help" != "" ]]; then
58 echo Usage: $(basename "$0") "[\-p PORT] [\-r DIRECTORY]"
66 if [[ $root[1] != \*(Aq/\*(Aq ]]; then root="$PWD/$root"; fi
68 # now use the function:
76 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\&.
79 Suffix aliases are supported in zsh since version 4\&.2\&.0\&. Some examples:
93 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:
99 $ alias \-g C=\*(Aq| wc \-l\*(Aq
100 $ grep alias ~/\&.zsh/* C
107 Some more or less useful global aliases (choose whether they are useful or not for you on your own):
113 alias \-g \&.\&.\&.=\*(Aq\&.\&./\&.\&.\*(Aq
114 alias \-g \&.\&.\&.\&.=\*(Aq\&.\&./\&.\&./\&.\&.\*(Aq
115 alias \-g \&.\&.\&.\&.\&.=\*(Aq\&.\&./\&.\&./\&.\&./\&.\&.\*(Aq
116 alias \-g CA="2>&1 | cat \-A"
117 alias \-g C=\*(Aq| wc \-l\*(Aq
118 alias \-g D="DISPLAY=:0\&.0"
119 alias \-g DN=/dev/null
120 alias \-g ED="export DISPLAY=:0\&.0"
121 alias \-g EG=\*(Aq|& egrep\*(Aq
122 alias \-g EH=\*(Aq|& head\*(Aq
123 alias \-g EL=\*(Aq|& less\*(Aq
124 alias \-g ELS=\*(Aq|& less \-S\*(Aq
125 alias \-g ETL=\*(Aq|& tail \-20\*(Aq
126 alias \-g ET=\*(Aq|& tail\*(Aq
127 alias \-g F=\*(Aq | fmt \-\*(Aq
128 alias \-g G=\*(Aq| egrep\*(Aq
129 alias \-g H=\*(Aq| head\*(Aq
130 alias \-g HL=\*(Aq|& head \-20\*(Aq
131 alias \-g Sk="*~(*\&.bz2|*\&.gz|*\&.tgz|*\&.zip|*\&.z)"
132 alias \-g LL="2>&1 | less"
134 alias \-g LS=\*(Aq| less \-S\*(Aq
135 alias \-g MM=\*(Aq| most\*(Aq
136 alias \-g M=\*(Aq| more\*(Aq
137 alias \-g NE="2> /dev/null"
138 alias \-g NS=\*(Aq| sort \-n\*(Aq
139 alias \-g NUL="> /dev/null 2>&1"
140 alias \-g PIPE=\*(Aq|\*(Aq
141 alias \-g R=\*(Aq > /c/aaa/tee\&.txt \*(Aq
142 alias \-g RNS=\*(Aq| sort \-nr\*(Aq
143 alias \-g S=\*(Aq| sort\*(Aq
144 alias \-g TL=\*(Aq| tail \-20\*(Aq
145 alias \-g T=\*(Aq| tail\*(Aq
146 alias \-g US=\*(Aq| sort \-u\*(Aq
147 alias \-g VM=/var/log/messages
148 alias \-g X0G=\*(Aq| xargs \-0 egrep\*(Aq
149 alias \-g X0=\*(Aq| xargs \-0\*(Aq
150 alias \-g XG=\*(Aq| xargs egrep\*(Aq
151 alias \-g X=\*(Aq| xargs\*(Aq
158 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\&.
160 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:
166 zstyle \*(Aq:completion:*\*(Aq use\-cache on
167 zstyle \*(Aq:completion:*\*(Aq cache\-path ~/\&.zsh/cache
173 Prevent CVS files/directories from being completed:
179 zstyle \*(Aq:completion:*:(all\-|)files\*(Aq ignored\-patterns \*(Aq(|*/)CVS\*(Aq
180 zstyle \*(Aq:completion:*:cd:*\*(Aq ignored\-patterns \*(Aq(*/)#CVS\*(Aq
186 Fuzzy matching of completions for when you mistype them:
192 zstyle \*(Aq:completion:*\*(Aq completer _complete _match _approximate
193 zstyle \*(Aq:completion:*:match:*\*(Aq original only
194 zstyle \*(Aq:completion:*:approximate:*\*(Aq max\-errors 1 numeric
200 And if you want the number of errors allowed by _approximate to increase with the length of what you have typed so far:
206 zstyle \-e \*(Aq:completion:*:approximate:*\*(Aq \e
207 max\-errors \*(Aqreply=($((($#PREFIX+$#SUFFIX)/3))numeric)\*(Aq
213 Ignore completion functions for commands you don\(cqt have:
219 zstyle \*(Aq:completion:*:functions\*(Aq ignored\-patterns \*(Aq_*\*(Aq
225 With helper functions like:
231 xdvi() { command xdvi ${*:\-*\&.dvi(om[1])} }
237 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:
243 zstyle \*(Aq:completion:*:*:xdvi:*\*(Aq menu yes select
244 zstyle \*(Aq:completion:*:*:xdvi:*\*(Aq file\-sort time
250 Completing process IDs with menu selection:
256 zstyle \*(Aq:completion:*:*:kill:*\*(Aq menu yes select
257 zstyle \*(Aq:completion:*:kill:*\*(Aq force\-list always
263 If you end up using a directory as argument, this will remove the trailing slash (usefull in ln)
269 zstyle \*(Aq:completion:*\*(Aq squeeze\-slashes true
275 cd will never select the parent directory (e\&.g\&.: cd \&.\&./<TAB>):
281 zstyle \*(Aq:completion:*:cd:*\*(Aq ignore\-parents parent pwd
287 Another method for \fIquick change directories\fR\&. Add this to your ~/\&.zshrc, then just enter \(lqcd \&...\&./dir\(rq
294 if [[ $LBUFFER = *\&.\&. ]]; then
300 zle \-N rationalise\-dot
301 bindkey \&. rationalise\-dot
306 .SS "UNSORTED/MISC examples"
308 Hint: A list of valid glob Qualifiers can be found in zshexpn(1)\&. See \(lqman 1 zshexpn | less \-p\(rq Qualifiers for details\&.
314 # Get the names of all files that *don\*(Aqt* match a pattern *anywhere* on the
315 # file (and without ``\-L\*(Aq\*(Aq because its GNUish)
316 $ print \-rl \-\- *(\&.^e{\*(Aqgrep \-q pattern $REPLY\*(Aq})
318 $ : *(\&.e{\*(Aqgrep \-q pattern $REPLY || print \-r \-\- $REPLY\*(Aq})
321 $ echo $[${RANDOM}%1000] # random between 0\-999
322 $ echo $[${RANDOM}%11+10] # random between 10\-20
323 $ echo ${(l:3::0:)${RANDOM}} # N digits long (3 digits)
326 $ echo "${(j::)${(@Oa)${(s::):\-hello}}}"
328 # Show newest directory
331 # random array element
332 $ FILES=( \&.\&.\&./files/* )
333 $ feh $FILES[$RANDOM%$#FILES+1]
335 # cat first line in all files in this dir
336 $ for file (*(ND\-\&.)) IFS= read \-re < $file
338 # test if a parameter is numeric
339 $ if [[ $1 == <\-> ]] ; then
345 # Show me all the \&.c files for which there doesn\*(Aqt exist a \&.o file\&.
346 $ print *\&.c(e_\*(Aq[[ ! \-e $REPLY:r\&.o ]]\*(Aq_)
348 # All files in /var/ that are not owned by root
349 $ ls \-ld /var/*(^u:root)
351 # All files for which the owner hat read and execute permissions
354 # The same, but also others dont have execute permissions
355 $ echo *(f:u+rx,o\-x:)
357 # brace expansion \- example
360 $ print \-r \-\- $^X\&.$^Y
361 A\&.+ A\&.\- B\&.+ B\&.\- C\&.+ C\&.\-
363 # Fetch the newest file containing the string \*(Aqfgractg*\&.log\*(Aq in the
364 # filename and contains the string \*(AqORA\-\*(Aq in it
365 $ file=(fgractg*\&.log(Nm0om[1]))
366 $ (($#file)) && grep \-l ORA\- $file
368 $ files=$( find \&. \-name \&. \-o \-prune \-name \*(Aqfgractg*>log\*(Aq \-mtime 0 \-print )
369 > if [ \-n "$files" ]; then
373 > file=$(ls \-td $files | head \-1)
374 > grep \-l ORA\- "$file"
377 # keep specified number of child processes running until entire task finished
378 $ zsh \-c \*(Aqsleep 1 & sleep 3 & sleep 2& print \-rl \-\- $jobtexts\*(Aq
380 # Remove zero length and \&.bak files in a directory
381 $ rm \-i *(\&.L0) *\&.bak(\&.)
383 # print out files that dont have extensions
384 $ printf \*(Aq%s\en\*(Aq ^?*\&.*
385 $ printf \*(Aq%s\en\*(Aq ^?*\&.[^\&.]*(D)
386 $ ls \-d \-\- ^?*\&.*(D)
388 # Finding files which does not contain a specific string
389 $ print \-rl file* | comm \-2 \-3 \- <(grep \-l string file*)\*(Aq
390 $ for f (file*(N)) grep \-q string $f || print \-r $f\*(Aq
392 # Show/Check whether a option is set or not\&. It works both with $options as
394 $ echo $options[correct]
399 # Count the number of directories on the stack
400 $ print $((${${(z)${(f)"$(dirs \-v)"}[\-1]}[1]} + 1)) # or
401 $ dirs \-v | awk \*(Aq{n=$1}END{print n+1}\*(Aq
403 # Matching all files which do not have a dot in filename
406 # Show only the ip\-address from ``ifconfig device\*(Aq\*(Aq
407 # ifconfig from net\-tools (Linux)
408 $ print ${${$(LC_ALL=C /sbin/ifconfig eth0)[7]}:gs/addr://}
409 # ifconfig from 4\&.2BSD {Free,Net,Open}BSD
410 $ print ${$(/sbin/ifconfig tun0)[6]}
412 # Ping all the IP addresses in a couple of class C\*(Aqs or all hosts
414 $ for i in {1\&.\&.254}; do ping \-c 1 192\&.168\&.13\&.$i; done
417 $ while ( [[ $I \-le 255 ]] ) ; do ping \-1 2 150\&.150\&.150\&.$I; let I++; done
419 $ for i in $(sed \*(Aqs/#\&.*//\*(Aq > /etc/hosts | awk \*(Aq{print $2}\*(Aq)
421 : echo "Trying $i \&.\&.\&. "
423 : echo \*(Aq=============================\*(Aq
426 # load all available modules at startup
429 $ for md ($module_path) m=($m $md/**/*(*e:\*(AqREPLY=${REPLY#$md/}\*(Aq::r))
432 # Rename all files within a directory such that their names get a numeral
433 # prefix in the default sort order\&.
434 $ i=1; for j in *; do mv $j $i\&.$j; ((i++)); done
435 $ i=1; for f in *; do mv $f $(echo $i | \e
436 awk \*(Aq{ printf("%03d", $0)}\*(Aq)\&.$f; ((i++)); done
437 $ integer i=0; for f in *; do mv $f $[i+=1]\&.$f; done
439 # Find (and print) all symbolic links without a target within the current
441 $ $ file **/*(D@) | fgrep broken
442 $ for i in **/*(D@); [[ \-f $i || \-d $i ]] || echo $i
443 $ echo **/*(@\-^\&./=%p)
444 $ print \-l **/*(\-@)
446 # List all plain files that do not have extensions listed in `fignore\*(Aq
447 $ ls **/*~*(${~${(j/|/)fignore}})(\&.)
448 # see above, but now omit executables
449 $ ls **/*~*(${~${(j/|/)fignore}})(\&.^*)
451 # Print out files that dont have extensions (require *setopt extendedglob*
452 # and *setopt dotglob*)
453 $ printf \*(Aq%s\en\*(Aq ^?*\&.*
455 # List files in reverse order sorted by name
456 $ print \-rl \-\- *(On)
458 $ print \-rl \-\- *(^on)
460 # Synonymic to ``ps ax | awk \*(Aq{print $1}\*(Aq\*(Aq\*(Aq
461 $ print \-l /proc/*/cwd(:h:t:s/self//)
463 # Get the PID of a process (without ``ps\*(Aq\*(Aq, ``sed\*(Aq\*(Aq, ``pgrep\*(Aq\*(Aq, \&.\&.
467 > for i in /proc/<\->/stat
469 > [[ "$(< $i)" = *\e((${(j:|:)~@})\e)* ]] && echo $i:h:t
473 # for X in \*(Aqn\*(Aq \*(Aqo\*(Aq \*(Aqp\*(Aq \*(Aqq\*(Aq \*(Aqr\*(Aq \*(Aqs\*(Aq \*(Aqt\*(Aq \*(Aqu\*(Aq \*(Aqv\*(Aq \*(Aqw\*(Aq \*(Aqx\*(Aq \*(Aqy\*(Aq; do \&.\&.\&.
474 $ for (( i = 36#n; i <= 36#y; i++ )); do
475 > print ${$(([##36]i)):l}
477 # or in combination with ``dc\*(Aq\*(Aq
478 $ print {$((##n))\&.\&.$((##y))}P\e 10P | dc
479 # or with ``eval\*(Aq\*(Aq
480 $ eval print \*(Aq${$(([##36]\*(Aq{$((36#n))\&.\&.$((36#y))}\*(Aq)):l}\*(Aq
482 # foreach in one line of shell
483 $ for f (*) print \-r \-\- $f
485 # copy a directory recursively without data/files
488 $ mkdir \-p \-\- $dirs
490 $ find \&. \-type d \-exec env d="$dest_root" \e
491 sh \-c \*(Aq exec mkdir \-p \-\- "$d/$1"\*(Aq \*(Aq{}\*(Aq \*(Aq{}\*(Aq \e;
493 # If `foo=23\*(Aq\*(Aq, then print with 10 digit with leading \*(Aq0\*(Aq\&.
495 $ print ${(r:10::0:)foo}
497 # find the name of all the files in their home directory that have
498 # more than 20 characters in their file names
499 print \-rl $HOME/${(l:20::?:)~:\-}*
502 $ print \-r \-\- ${(qq)m} > $nameoffile # save it
503 $ eval "m=($(cat \-\- $nameoffile)" # or use
504 $ m=("${(@Q)${(z)"$(cat \-\- $nameoffile)"}}") # to restore it
506 # get a "ls \-l" on all the files in the tree that are younger than a
507 # specified age (e\&.g "ls \-l" all the files in the tree that where
508 # modified in the last 2 days)
509 $ ls \-tld **/*(m\-2)
510 # This will give you a listing 1 file perl line (not à la ls \-R)\&.
511 # Think of an easy way to have a "ls \-R" style output with
512 # only files newer than 2 day old\&.
513 $ for d (\&. \&./**/*(/)) {
514 > print \-r \-\- $\*(Aq\en\*(Aq${d}:
517 > (($#l)) && ls \-ltd \-\- $l
521 # If you also want directories to be included even if their mtime
522 # is more than 2 days old:
523 $ for d (\&. \&./**/*(/)) {
524 > print \-r \-\- $\*(Aq\en\*(Aq${d}:
527 > (($#l)) && ls \-ltd \-\- $l
531 # And if you want only the directories with mtime < 2 days to be listed:
532 $ for d (\&. \&./**/*(N/m\-2)) {
533 > print \-r \-\- $\*(Aq\en\*(Aq${d}:
536 > (($#l)) && ls \-ltd \-\- $l
541 # print 42 ``\-\*(Aq\*(Aq
542 $ echo ${(l:42::\-:)}
543 # or use ``$COLUMS\*(Aq\*(Aq
544 $ echo ${(l:$COLUMNS::\-:)}
545 # and now with colors (require autoload colors ;colors)
546 $ echo "$bg[red]$fg[black]${(l:42::\-:)}"
548 # Redirect STDERR to a command like xless without redirecting STDOUT as well\&.
550 # but this executes the command asynchronously\&. To do it synchronously:
551 $ { { foo 1>&3 } 2>&1 | xless } 3>&1
553 # Rename all MP3\-Files from name with spaces\&.mp3 to Name With Spaces\&.mp3
554 $ for i in *\&.mp3; do
555 > mv $i ${${(C)i}:s/Mp3/mp3/}
558 # Match file names containing only digits and ending with \&.xml (require
560 $ ls \-l [0\-9]##\&.xml
563 # Remove all "non txt" files
566 # Move 200 files from a directory into another
567 $ mv \-\- *([1,200]) /another/Dir
569 # Convert images (foo\&.gif => foo\&.png):
570 $ for i in **/*\&.gif; convert $i $i:r\&.png
572 # convert a collection of mp3 files to wave or cdr,
573 # e\&.g\&. file\&.wav \-> file\&.mp3)
574 $ for i (\&./*\&.mp3){mpg321 \-\-w \- $i > ${i:r}\&.wav}
576 # Download with LaTeX2HTML created Files (for example the ZSH\-Guide):
577 $ for f in http://zsh\&.sunsite\&.dk/Guide/zshguide{,{01\&.\&.08}}\&.html; do
578 > lynx \-source $f >${f:t}
581 # Move all files in dir1 and dir2 that have line counts greater than 10 to
582 # another directory say "/more10"
583 $ mv dir[12]/**/*\&.cr(\-\&.e{\*(Aq((`wc \-l < $REPLY` > 10))\*(Aq}) /more10
585 # Make with dpkg a master\-list of everyfile that it has installed
586 $ diff <(find / | sort) <(cat /var/lib/dpkg/info/*\&.list | sort)
588 # Replace this fucking Escape\-Sequences:
589 $ autoload colors ; colors
590 $ print "$bg[cyan]$fg[blue]You are a idiot" >> /dev/pts/3
592 # Get ASCII value of a character
593 $ char=N ; print $((#char))
595 # Filename "Erweiterung"
596 # Note: The (N) says to use the nullglob option for this particular
598 $ for i in *\&.o(N); do
602 # Rename files; i\&. e\&. FOO to foo and bar to BAR
603 $ for i in *(\&.); mv $i ${i:l} # `FOO\*(Aq to `foo\*(Aq
604 $ for i in *(\&.); mv $i ${i:u} # `bar to `BAR\*(Aq
606 # Show all suid\-files in $PATH
607 $ ls \-latg ${(s\&.:\&.)PATH} | grep \*(Aq^\&.\&.\&.s\*(Aq
609 $ print \-l ${^path}/*(Ns,S)
610 # or show only executables with a user given pattern
611 $ print \-l ${^path}/*vim*(*N)
613 # gzip files when containing a certain string
614 $ gzip ${(ps:\e0:)"$(grep \-lZ foobar \&./*\&.txt(\&.))"}
616 # A small one\-liner, that reads from stdin and prints to stdout the first
617 # unique line i\&. e\&. does not print lines that have been printed before
618 # (this is similar to the unique command, but unique can only handle
620 $ IFS=$\*(Aq\en\en\*(Aq; print \-rl \-\- ${(Oau)${(Oa)$(cat file;echo \&.)[1,\-2]}}
622 # Lists every executable in PATH
623 $ print \-l ${^path}/*(\-*N)
625 # Match all \&.c files in all subdirectories, _except_ any SCCS subdirectories?
626 $ ls **/*\&.c~(*/)#SCCS/*
628 # List all `README\*(Aq \- files case\-insensitive with max\&. one typo
629 $ ls **/*(#ia2)readme
631 # case insensitive checking for variables
632 $ if [[ $OSTYPE == (#i)LINUX*(#I) ]]; then
633 > echo "Penguin on board\&."
635 > echo "Not a Linux\&."
641 .SS "(Recursive) Globbing \- Examples"
643 A list of valid glob Qualifiers can be found in zshexpn(1)\&. \fBNote:\fR **/ is equivalent to (*/)#! For example:
649 $ print (*/)#zsh_us\&.ps
650 zsh\-4\&.2\&.3/Doc/zsh_us\&.ps
651 $ print **/zsh_us\&.ps
652 zsh\-4\&.2\&.3/Doc/zsh_us\&.ps
662 # Search for `README\*(Aq in all Subdirectories
665 # find directories that contain both "index\&.php" and "index\&.html", or in
666 # general, directories that contain more than one file matching "index\&.*"
667 $ ls **/*(D/e:\*(Aq[[ \-e $REPLY/index\&.php && \-e $REPLY/index\&.html ]]\*(Aq:)
669 $ ls **/*(D/e:\*(Aql=($REPLY/index\&.*(N)); (( $#l >= 2 ))\*(Aq:)
671 # Find command to search for directory name instead of basename
672 $ print \-rl /**/*~^*/path(|/*)
674 $ find / | grep \-e /path/ \-e \*(Aq/path$\*(Aq
676 # Print he path of the directories holding the ten biggest C regular files
677 # in the current directory and subdirectories\&.
678 $ print \-rl \-\- **/*\&.c(D\&.OL[1,10]:h) | sort \-u
680 # Find files with size == 0 and send a mail
681 $ files=(**/*(ND\&.L0m+0m\-2))
682 > (( $#files > 0 )) && print \-rl \-\- $files | \e
683 mailx \-s "empty files" foo@bar\&.tdl
686 $ chmod 700 **/(\&.) # Only files
687 $ chmod 700 **/(/) # Only directories
689 # print out all of the files in that directory in 2 columns
690 $ print \-rC2 \-\- ${1:[\&.\&.\&.]}/*(D:t)
691 # ^\- number ob columns
692 # or \- if you feel concerned about special characters \- use
693 $ list=(${1:[\&.\&.\&.]}/*(ND:t))
694 $ (($#list)) && print \-rC2 \-\- ${(V)list}
696 # Search all files in /home/*/*\-mail/ with a setting ``chmod \-s\*(Aq\*(Aq flag
697 # (recursive, include dotfiles) remove the setgid/setuid flag and print
699 $ chmod \-s /home/*/*\-mail(DNs,S) /home/*/*\-mail/**/*(DNs,S))
700 # or with a small script
701 $ for file (/home/*/*\-mail(DNs,S) /home/*/*\-mail/**/*(DNs,S)) {
702 > print \-r \-\- $file
703 > chmod \-s $file && print \-r fixed $file
705 # or use ``zargs\*(Aq\*(Aq (require autoload zargs) prevent the arg list too
707 $ zargs /home/*/*\-mail(DNs,S) /home/*/*\-mail/**/*(DNs,S)) \-\- chmod \-s
709 # List files beginning at `foo23\*(Aq upwards (foo23, foo24, foo25, \&.\&.)
712 # get all files that begin with the date strings from June 4 through
714 $ ls \-l 200406{04\&.\&.10}*(N)
715 # or if they are of the form 200406XX (require ``setopt extended_glob\*(Aq\*(Aq
716 $ ls \-l 200306<4\-10>\&.*
718 # remove spaces from filenames
719 $ for a in \&./**/*\e *(Dod); do mv $a ${a:h}/${a:t:gs/ /_}; done
721 # Show only all *\&.c and *\&.h \- Files
724 # Show only all *\&.c \- files and ignore `foo\&.c\*(Aq
727 # show data to *really* binary format
728 $ zsh \-ec \*(Aqwhile {} {printf %\&.8x $n;repeat 8 \e
729 > {read \-ku0 a printf \e %\&.8d $(([##2]#a))};print;((n+=8))}\*(Aq < binary
731 # Show only world\-readable files
734 # List files in the current directory are not writable by the owner
735 $ print \-l ~/*(ND\&.^w)
737 # find and delete the files which are older than a given parameter
738 # (seconds/minutes/hours)
739 # deletes all regular file in /Dir that are older than 3 hours
740 $ rm \-f /Dir/**/*(\&.mh+3)
741 # deletes all symlinks in /Dir that are older than 3 minutes
742 $ rm \-f /Dir/**/*(@mm+3)
743 # deletes all non dirs in /Dir that are older than 30 seconds
744 $ rm \-f /Dir/**/*(ms+30^/)
745 # deletes all folders, sub\-folders and files older than one hour
746 $ rm \&./**/*(\&.Dmh+1,\&.DL0)
747 # deletes all files more than 6 hours old
749 # removes all files but the ten newer ones (delete all but last 10
750 # files in a directory)
751 $ rm \&./*(Om[1,\-11])
752 Note: If you get a arg list too long, you use the builtin rm\&. For
754 $ zmodload zsh/files ; rm \-f **/*(mh+6)
755 or use the zargs function:
756 $ autoload zargs ; zargs **/*(mh+6) \-\- rm \-f
758 # A User\*(Aqs Guide to the Z\-Shell /5\&.9: Filename Generation and Pattern
759 # Matching find all files in all subdirectories, searching recursively,
760 # which have a given name, case insensitive, are at least 50 KB large,
761 # no more than a week old and owned by the root user, and allowing up
762 # to a single error in the spelling of the name\&. In fact, the required
763 # expression looks like this:
764 $ ls **/(#ia1)name(LK+50mw\-1u0)
766 # Change the UID from 102 to 666
767 $ chown 666 **/*(u102)
769 # List all files which have not been updated since last 10 hours
770 $ print \-rl \-\- *(Dmh+10^/)
772 # delete only the oldest file in a directory
773 $ rm \&./*filename*(Om[1])
775 # Sort the output from `ls \-l\*(Aq by file size
778 # find most recent file in a directory
779 $ setopt dotglob ; print directory/**/*(om[1])
781 # Show only empty files which nor `group\*(Aq or `world writable\*(Aq
782 $ ls *(L0f\&.go\-w\&.)
784 # Find \- and list \- the ten newest files in directories and subdirs\&.
786 $ print \-rl \-\- **/*(Dom[1,10])
788 # Print only 5 lines by "ls" command (like ``ls \-laS | head \-n 5\*(Aq\*(Aq)\&.
789 $ ls \-fl *(DOL[1,5])
791 # Display the 5\-10 last modified files\&.
792 $ print \-rl \-\- /path/to/dir/**/*(D\&.om[5,10])
794 # Find all files without a valid owner\&.
795 $ chmod someuser /**/*(D^u:${(j\&.:u:\&.)${(f)"$(</etc/passwd)"}%%:*}:)
797 # Find all the empty directories in a tree\&.
798 $ for f in ***/*(/l2); do foo=($f/*(N)); [[ \-z $foo ]] && print $f; done
799 # Note:Since Zsh 4\&.2\&.1 the glob qualifier F indicates a non\-empty directory\&.
800 # Hence *(F) indicates all subdirectories with entries, *(/^F) means all
801 # subdirectories with no entries\&.
804 # Remove empty directories afterwards\&.
805 $ rmdir \&./**/*(/od) 2> /dev/null
807 # Show only files which are owned by group `users\*(Aq\&.
813 .SS "Modifiers usage"
815 Modifiers are a powerful mechanism that let you modify the results returned by parameter, filename and history expansion\&. See zshexpn(1) for details\&.
821 # NOTE: Zsh 4\&.3\&.4 needed!
823 # files modified today
824 $ print *(e:age today now:)
825 # files modified since 5 pm
826 $ print *(e\-age 17:00 now\-)
827 # \&.\&.\&. since 5 o\*(Aqclock yesterda
828 $ print *(e\-age yesterday,17:00 now\-)
829 # \&.\&.\&. from last Christmas before today
830 $ print *(e\-age 2006/12/25 today\-)
831 # \&.\&.\&. before yesterday
832 $ print *(e\-age 1970/01/01 yesterday\-)
833 # all files modified between the start of those dates
834 $ print *(e:age 2006/10/04 2006/10/09:)
835 # all files modified on that date
836 $ print *(e:age 2006/10/04:)
838 $ print *(e\-age 2006/10/04:10:15 2006/10/04:10:45\-)
840 # Remove a trailing pathname component, leaving the head\&. This works like
845 # Remove all leading pathname components, leaving the tail\&. This works
846 # like `basename\*(Aq\&.
850 # Remove the suffix from each file (*\&.sh in this example)
851 $f:e is $f file extension
852 :h \-\-> head (dirname)
853 :t \-\-> tail (basename)
854 :r \-\-> rest (extension removed)
855 $ for f (*\&.sh) mv $f $f:r
857 # Remove a filename extension of the form `\&.xxx\*(Aq, leaving the root name\&.
863 # Remove all but the extension\&.
870 # Print the new command but do not execute it\&. Only works with history
877 # Quote the substituted words, escaping further substitutions\&.
884 # Convert the words to all lowercase\&.
891 # Convert the words to all uppercase\&.
898 # convert 1st char of a word to uppercase
899 $ foo="one two three four"
900 $ print \-r \-\- "${(C)foo}"
906 .SS "Redirection\-Examples"
908 See zshmisc(1) for more informations (or less ${^fpath}/zmv(N))
914 # Append `exit 1\*(Aq at the end of all *\&.sh \- files
915 $ echo "exit 1" >> *\&.sh
917 # adding files to foobar\&.tar\&.gz
918 $ eval set =(gunzip < foobar\&.tar\&.gz) \*(Aq
919 tar rf $1 additional\&.txt &&gzip < $1 > foobar\&.tar\&.gz\*(Aq
921 # Redirect output to a file AND display on screen
922 $ foobar >&1 > file1 > file2 > \&.\&.
924 # pipe single output to multiple inputs
925 $ zcat foobar\&.Z >> (gzip \-9 > file1\&.gz) \e
926 >> (bzip2 \-9 > file1\&.bz2) \e
927 >> (acb \-\-best > file1\&.acb)
929 # Append /etc/services at the end of file `foo\*(Aq and `bar\*(Aq
930 $ cat /etc/services >> foo >> bar
933 $ echo An error >&2 2>&1 | sed \-e \*(Aqs/A/I/\*(Aq
935 # send standard output of one process to standard input of several processes
938 $ process1 > >(process1) > >(process2)
940 # initializing a variable and simultaneously keeping terminal output
942 $ { a=$(command >&1 >& 3 3 > &\- 2>&1);} 3>&1
944 # redirect stderr two times
945 $ setopt multios ; program 2> file2 > file1 2>&1
947 # Duplicating stdout and stderr to a logfile
948 $ exec 3>&1 > logfile 2>&2 2>&1 >&3 3>&\-
950 # redirect stderr (only) to a file and to orig\&. stderr:
951 $ command 2>&2 2>stderr
952 # redirect stderr and stdout to separate files and both to orig\&. stdout:
953 $ command 2>&1 1>&1 2>stderr 1>stdout
954 # redirect stderr and stdout to separate files and stdout to orig\&. stdout
955 # AND stderr to orig\&. stderr:
956 $ command 2>&2 1>&1 2>stderr 1>stdout
958 # More fun with STDERR ;)
959 $ \&./my\-script\&.sh 2> >(grep \-v moron >error\&.log)|process\-output >output\&.log
960 $ echo "Thats STDOUT" >>(sed \*(Aqs/stdout/another example/\*(Aq > foobar)
965 .SS "ZMV\-Examples (require autoload zmv)"
967 \fBNote:\fR \fI\-n\fR means no execution (just print what would happen)\&. At
973 # Remove illegal characters in a fat32 file system\&. Illegal characters are
975 # NOTE: ``\-Q\*(Aq\*(Aq and (D) is to include hidden files\&.
976 $ unwanted=\*(Aq[:;*?\e"<>|]\*(Aq
977 $ zmv \-Q "(**/)(*$~unwanted*)(D)" \*(Aq$1${2//$~unwanted/}\*(Aq
979 # Changing part of a filename (i\&. e\&. "file\-hell\&.name" \-> "file\-heaven\&.name")
980 $ zmv \*(Aq(*)hell(*)\*(Aq \*(Aq${1}heaven${2}\*(Aq
982 $ zmv \*(Aq*\*(Aq \*(Aq$f:s/hell/heaven/\*(Aq
984 # remove round bracket within filenames
985 # i\&. e\&. foo\-(bar)\&.avi \-> foo\-bar\&.avi
986 $ zmv \*(Aq*\*(Aq \*(Aq${f//[()]/}\*(Aq
988 # serially all files (foo\&.foo > 1\&.foo, fnord\&.foo > 2\&.foo, \&.\&.)
991 1\&.c asd\&.foo bla\&.foo fnord\&.foo foo\&.fnord foo\&.foo
992 $ c=1 zmv \*(Aq*\&.foo\*(Aq \*(Aq$((c++))\&.foo\*(Aq
994 1\&.c 1\&.foo 2\&.foo 3\&.foo 4\&.foo foo\&.fnord
996 # Rename "file\&.with\&.many\&.dots\&.txt" by substituting dots (exept for the last
998 $ touch {1\&.\&.20}\-file\&.with\&.many\&.dots\&.txt
999 $ zmv \*(Aq(*\&.*)(\&.*)\*(Aq \*(Aq${1//\&./ }$2\*(Aq
1001 # Remove the first 4 chars from a filename
1002 $ zmv \-n \*(Aq*\*(Aq \*(Aq$f[5,\-1]\*(Aq # NOTE: The "5" is NOT a mistake in writing!
1004 # Rename names of all files under the current Dir to lower case, but keep
1005 # dirnames as\-is\&.
1006 $ zmv \-Qv \*(Aq(**/)(*)(\&.D)\*(Aq \*(Aq$1${(L)2}\*(Aq
1008 # replace all 4th character, which is "1", with "2" and so on
1010 $ zmv \*(Aq(???)1(???[1\-4]\&.txt)\*(Aq \*(Aq${1}2${2}\*(Aq
1012 # Remove the first 15 characters from a string
1013 $ touch 111111111111111{a\-z}
1015 $ zmv \*(Aq*\*(Aq \*(Aq$f[16,\-1]\*(Aq
1017 # Replace spaces (any number of them) with a single dash in file names
1019 $ zmv \-n \*(Aq(**/)(* *)\*(Aq \*(Aq$1${2//( #\-## #| ##)/\-}\*(Aq
1021 $ find \&. \-depth \-name \*(Aq* *\*(Aq \-exec bash \-c \*(Aq
1026 > newname=${name//*([ \-]) *([ \-])/\-}
1027 > mv \-i \-\- "$file" "$Dir/$newname"\*(Aq {} {} \e;
1029 # Clean up file names and remove special characters
1031 $ zmv \-n \*(Aq(**/)(*)\*(Aq \*(Aq$1${2//[^A\-Za\-z0\-9\&._]/_}\*(Aq
1033 # Add *\&.py to a bunch of python scripts in a directory (some of them end
1034 # in *\&.py and give them all a proper extension
1036 $ zmv \-n \*(Aq(**/)(con*)(#qe,file $REPLY | grep "python script",)\*(Aq \*(Aq$1$2\&.py\*(Aq
1038 # lowercase all extensions (i\&. e\&. *\&.JPG) incl\&. subfolders
1040 $ zmv \*(Aq(**/)(*)\&.(#i)jpg\*(Aq \*(Aq$1$2\&.jpg\*(Aq
1042 $ find Dir \-name \*(Aq*\&.[jJ][pP][gG]\*(Aq \-print | while read f
1046 > *) mv "$f" "${f%\&.*}\&.jpg" ;
1050 # remove leading zeros from file extension
1053 filename\&.001 filename\&.003 filename\&.005 filename\&.007 filename\&.009
1054 filename\&.002 filename\&.004 filename\&.006 filename\&.008 filename\&.010
1055 $ zmv \*(Aq(filename\&.)0##(?*)\*(Aq \*(Aq$1$2\*(Aq
1057 filename\&.1 filename\&.10 filename\&.2 filename\&.3 filename\&.4 filename\&.5 \&.\&.
1062 foo_10\&.jpg foo_2\&.jpg foo_3\&.jpg foo_4\&.jpg foo_5\&.jpg foo_6\&.jpg \&.\&.
1063 $ zmv \-fQ \*(Aqfoo_(<0\->)\&.jpg(\&.nOn)\*(Aq \*(Aqfoo_$(($1 + 1))\&.jpg\*(Aq
1065 foo_10\&.jpg foo_11\&.jpg foo_3\&.jpg foo_4\&.jpg foo_5\&.jpg \&.\&.\&.
1067 # adding leading zeros to a filename (1\&.jpg \-> 001\&.jpg, \&.\&.
1069 $ zmv \*(Aq(<1\->)\&.jpg\*(Aq \*(Aq${(l:3::0:)1}\&.jpg\*(Aq
1071 # See above, but now only files with a filename >= 30 chars
1073 $ c=1 zmv "${(l:30\-4::?:)}*\&.foo" \*(Aq$((c++))\&.foo\*(Aq
1075 # Replace spaces in filenames with a underline
1077 $ zmv \*(Aq* *\*(Aq \*(Aq$f:gs/ /_\*(Aq
1079 # Change the suffix from *\&.sh to *\&.pl
1081 $ zmv \-W \*(Aq*\&.sh\*(Aq \*(Aq*\&.pl\*(Aq
1083 # Add a ""\&.txt" extension to all the files within ${HOME}
1084 # ``\-\&.\*(Aq\*(Aq is to only rename regular files or symlinks to regular files,
1085 # ``D\*(Aq\*(Aq is to also rename hidden files (dotfiles))
1087 $ zmv \-Q \*(Aq/home/**/*(D\-\&.)\*(Aq \*(Aq$f\&.txt\*(Aq
1088 # Or to only rename files that don\*(Aqt have an extension:
1089 $ zmv \-Q \*(Aq/home/**/^?*\&.*(D\-\&.)\*(Aq \*(Aq$f\&.txt\*(Aq
1091 # Recursively change filenames with characters ? [ ] / = + < > ; : " , \- *
1093 $ chars=\*(Aq[][?=+<>;",*\-]\*(Aq
1094 $ zmv \*(Aq(**/)(*)\*(Aq \*(Aq$1${2//$~chars/%}\*(Aq
1096 # Removing single quote from filenames (recursively)
1098 $ zmv \-Q "(**/)(*\*(Aq*)(D)" "\e$1\e${2//\*(Aq/}"
1100 # When a new file arrives (named file\&.txt) rename all files in order to
1101 # get (e\&. g\&. file119\&.txt becomes file120\&.txt, file118\&.txt becomes
1102 # file119\&.txt and so on ending with file\&.txt becoming file1\&.txt
1104 $ zmv \-fQ \*(Aqfile([0\-9]##)\&.txt(On)\*(Aq \*(Aqfile$(($1 + 1))\&.txt\*(Aq
1106 # lowercase/uppercase all files/directories
1108 $ zmv \*(Aq(*)\*(Aq \*(Aq${(L)1}\*(Aq # lowercase
1109 $ zmv \*(Aq(*)\*(Aq \*(Aq${(U)1}\*(Aq # uppercase
1111 # Remove the suffix *\&.c from all C\-Files
1113 $ zmv \*(Aq(*)\&.c\*(Aq \*(Aq$1\*(Aq
1115 # Uppercase only the first letter of all *\&.mp3 \- files
1117 $ zmv \*(Aq([a\-z])(*)\&.mp3\*(Aq \*(Aq${(C)1}$2\&.mp3\*(Aq
1119 # Copy the target `README\*(Aq in same directory as each `Makefile\*(Aq
1121 $ zmv \-C \*(Aq(**/)Makefile\*(Aq \*(Aq${1}README\*(Aq
1123 # Removing single quote from filenames (recursively)
1125 $ zmv \-Q "(**/)(*\*(Aq*)(D)" "\e$1\e${2//\*(Aq/}"
1127 # Rename pic1\&.jpg, pic2\&.jpg, \&.\&. to pic0001\&.jpg, pic0002\&.jpg, \&.\&.
1129 $ zmv \*(Aqpic(*)\&.jpg\*(Aq \*(Aqpic${(l:4::0:)1}\&.jpg\*(Aq
1130 $ zmv \*(Aq(**/)pic(*)\&.jpg\*(Aq \*(Aq$1/pic${(l:4::0:)2}\&.jpg\*(Aq # recursively
1135 .SS "Module\-Examples"
1137 Please read zshmodules(1) first!
1140 .nr an-no-space-flag 1
1144 \fBzsh/pcre (require zmodload zsh/pcre)\fR
1151 # Copy files of a certain period (date indicated in the filenames)
1153 $ ls \-d \-\- *(e:\*(Aq[[ $REPLY \-pcre\-match pcre\-regexp ]]\*(Aq:)
1155 $ m() { [[ $1 \-pcre\-match pcre\-regexp ]] }
1164 .nr an-no-space-flag 1
1168 \fBzsh/clone (require zmodload zsh/clone)\fR
1175 # Creates a forked instance of the current shell ($! is set to zero) and
1176 # execute ``command\*(Aq\*(Aq on /dev/tty8 (for this example)\&.
1177 $ zmodload zsh/clone
1178 $ clone /dev/tty8 && (($! == 0)) && exec command
1186 .nr an-no-space-flag 1
1190 \fBzsh/datetime (require zmodload zsh/datetime)\fR
1197 $ zmodload zsh/datetime
1198 $ alias datereplacement=\*(Aqstrftime "%Y\-%m\-%d" $EPOCHSECONDS\*(Aq
1199 $ export DATE=`datereplacement`
1202 # strip date from filename
1203 $ $ zmodload zsh/datetime
1204 $ setopt extendedglob
1205 $ touch aaa_bbb_20041212_c\&.dat eee_fff_20051019_g\&.dat
1206 $ strftime \-s pattern \e
1207 \*(Aq???_???_<0\-%Y%m%d>_?\&.dat\*(Aq $((EPOCHSECONDS \- 365 * 24 * 60 * 60 / 2))
1208 $ print \-rl \-\- $~pattern
1209 aaa_bbb_20041212_c\&.dat
1210 $ print \-rl \-\- $pattern
1211 ???_???_<0\-20050815>_?\&.dat
1213 # Search files size == 0, to be based on the file name containing a date
1214 # rather than the "last modified" date of the file
1215 $ zmodload \-i zsh/datetime
1216 $ strftime \-s file "abc_de_%m%d%Y\&.dat" $((EPOCHSECONDS \- 24 * 60 * 60 ))
1217 $ files=(**/$file(N\&.L0))
1218 $ (( $#files > 0 )) && print \-rl \-\- $files | \e
1219 mailx \-s "empty files" foo@bar\&.tdl
1227 .nr an-no-space-flag 1
1231 \fBzsh/stat (require zmodload zsh/stat)\fR
1238 # test if a symbolic link links to a certain file
1239 $ zmodload \-i zsh/stat
1240 $ ! stat \-LH s foo\&.ln || [[ $s[link] != "foo\&.exe" ]] || ln \-sf foo\&.exe foo\&.ln
1242 # comparing file dates
1246 $ touch bar & sleep 5 & touch foo
1247 $ echo $file1 is $(($(stat +mtime $file2) \- \e
1248 $(stat +mtime $file1))) seconds older than $file2\&.
1249 bar is 5 seconds older than foo
1251 # list the files of a disk smaller than some other file
1253 $ stat \-A max +size some\-other\-file
1254 $ print \-rl \&./**/*(D\&.L\-$max)
1256 # List the top 100 biggest files in a disk
1258 $ ls \-fld \&./**/*(d`stat +device \&.`OL[1,100])
1260 # Get only the user name and the file names from (like
1261 # ls \-l * | awk \*(Aq{print $3" " $8}\*(Aq)
1264 > stat \-sA user +uid \-\- "$file" &&
1265 > print \-r \-\- "$user" "$file"
1268 # get the difference between actual bytes of file and allocated bytes of file
1270 $ print $(($(stat +block \-\- file) * 512 \- $(stat +size \-\- file)))
1273 # ``D\*(Aq\*(Aq : to include dot files (d lowercase is for device)
1274 # ``O\*(Aq\*(Aq : reverse Ordered (o lowercase for non\-reverse order)
1275 # ``L\*(Aq\*(Aq : by file Length (l is for number of links)
1276 # ``[1]\*(Aq\*(Aq: return only first one
1278 $ stat +size \&./*(DOL[1])
1280 # file size in bytes
1282 $ stat \-L +size ~/\&.zshrc
1285 # Delete files in a directory that hasn\*(Aqt been accessed in the last ten days
1286 # and send ONE mail to the owner of the files informing him/her of the files\*(Aq
1288 $ zmodload zsh/stat zsh/files
1289 $ typeset \-A f; f=()
1290 $ rm \-f /path/**/*(\&.a+10e{\*(Aqstat \-sA u +uidr $REPLY; f[$u]="$f[$u]$REPLY"\*(Aq})
1291 $ for user (${(k)f}) {print \-rn $f[$user]|mailx \-s "\&.\&.\&." $user}
1293 # Get a "ls \-l" on all the files in the tree that are younger than a
1296 $ for d (\&. \&./**/*(N/m\-2))
1297 > print \-r \-\- $\*(Aq\en\*(Aq$d: && cd $d && {
1298 > for f (*(Nm\-2om))
1299 > stat \-F \*(Aq%b %d %H:%M\*(Aq \-LsAs \-\- $f &&
1300 > print \-r \-\- $s[3] ${(l:4:)s[4]} ${(l:8:)s[5]} \e
1301 > ${(l:8:)s[6]} ${(l:8:)s[8]} $s[10] $f ${s[14]:+\-> $s[14]}
1305 # get file creation date
1307 $ stat \-F \*(Aq%d %m %Y\*(Aq +mtime ~/\&.zshrc
1309 $ stat \-F \*(Aq%D\*(Aq +mtime ~/\&.zshrc
1318 .nr an-no-space-flag 1
1322 \fBzsh/files (require zmodload zsh/files)\fR
1329 # search a directory for files containing a certain string then copy those
1330 # files to another directory\&.
1331 $ zmodload zsh/files
1332 $ IFS=$\*(Aq\e0\*(Aq
1333 $ cp $(grep \-lZr foobar \&.) otherdirectory
1341 .nr an-no-space-flag 1
1345 \fBzsh/mapfile (require zmodload zsh/mapfile)\fR
1352 # grepping for two patterns
1353 $ zmodload zsh/mapfile
1355 $ pattern2="bar foo"
1356 $ print \-l \&./**/*(DN\&.e{\*(Aqz=$mapfile[$REPLY] && [[ $z = *$pattern1* && \e
1357 $z = *$pattern2* ]]\*(Aq})
1358 # or a solution in combination with zsh/pcre
1359 $ zmodload \-i zsh/mapfile zsh/pcre
1361 $ pattern2="bar foo"
1362 $ pcre_compile "(?s)(?=\&.*?$pattern1)\&.*?$pattern2"
1364 $ print \-l \&./**/*(DN\&.e{\*(Aqpcre_match $mapfile[$REPLY]\*(Aq})
1366 # equivalent for ``less /etc/passwd | grep \-v root\*(Aq\*(Aq
1367 $ zmodload zsh/mapfile
1368 $ IFS=$\*(Aq\en\en\*(Aq
1369 $ print \-rl \-\- ${${=mapfile[/etc/passwd]}:#*root*}
1370 # or \- for case insensitive
1371 $ setopt extendedglob
1372 $ print \-rl \-\- ${${=mapfile[/etc/passwd]}:#*(#i)root*}
1374 # If a XML\-file contains stuff like ``<TAGA/>\*(Aq\*(Aq and ``<TAGB/>\*(Aq\*(Aq, number
1375 # this empty tags (ones ending in \*(Aq/>\*(Aq) so if encountered in the same
1376 # order, the preceeding tags would become ``<TAGA/>1</TAGA>\*(Aq\*(Aq and
1377 # ``<TAGB/>2</TAGB>\*(Aq\*(Aq
1378 $ zmodload zsh/mapfile
1380 $ apfile[data\&.xml\&.new]=${(S)mapfile[data\&.xml]//\e
1381 > (#im)<TAGA>*<\e/TAGA>/<TAGA>$((++cnt))<\e/TAGA>}
1383 # removing all files in users Maildir/new that contain ``filename="gone\&.src\*(Aq\*(Aq
1384 $ zmodload zsh/{files,mapfile}
1385 $ rm \-f /u1/??/*/Maildir/new/100*(\&.e{\*(Aq[[ $mapfile[$REPLY] == \e
1386 *filename=\e"gone\&.scr\e"* ]]\*(Aq})
1388 # Grep out the Title from a postscript file and append that value to the
1389 # end of the filename
1391 $ zmodload zsh/mapfile
1392 $ zmv \*(Aq(*)\&.ps\*(Aq \*(Aq$1\-${${${mapfile[$f]##*%%Title: }%% *}//[^a\-zA\-Z0\-9_]/}\&.ps\*(Aq
1400 .nr an-no-space-flag 1
1404 \fBzsh/mathfunc (require zmodload zsh/mathfunc)\fR
1411 $ zmodload zsh/mathfunc
1412 $ echo $(( sin(1/4\&.0)**2 + cos(1/4\&.0)**2 \- 1 ))
1413 \-1\&.1102230246251565e\-16
1414 $ echo $(( pi = 4\&.0 * atan(1\&.0) ))
1415 3\&.1415926535897931
1416 $ echo $(( f = sin(0\&.3) ))
1417 0\&.29552020666133955
1418 $ print $((1e12 * rand48()))
1419 847909677310\&.23413
1420 $ print $(( rand48(seed) ))
1421 0\&.01043488334700271
1429 .nr an-no-space-flag 1
1433 \fBzsh/termcap (require zmodload zsh/termcap)\fR
1440 $ zmodload \-ab zsh/termcap echotc
1441 $ GREEN=`echotc AF 2`
1442 $ YELLOW=`echotc AF 3`
1444 $ BRIGHTRED=`echotc md ; echotc AF 1`
1445 $ print \-l ${GREEN}green ${YELLOW}yellow ${RED}red ${BRIGHTRED}brightred
1453 .nr an-no-space-flag 1
1457 \fBzsh/zpty (require zmodload zsh/zpty)\fR
1467 # ``\-r\*(Aq\*(Aq: read the output of the command name\&.
1468 # ``z\*(Aq\*(Aq : Parameter
1469 $ zpty \-r PW z \*(Aq*password:\*(Aq
1470 # send the to command name the given strings as input
1472 $ zpty \-r PW z \*(Aq*password:\*(Aq
1474 # The second form, with the \-d option, is used to delete commands
1475 # previously started, by supplying a list of their names\&. If no names
1476 # are given, all commands are deleted\&. Deleting a command causes the HUP
1477 # signal to be sent to the corresponding process\&.
1486 .nr an-no-space-flag 1
1490 \fBzsh/net/socket (require zmodload zsh/net/socket)\fR
1497 # ``\-l\*(Aq\*(Aq: open a socket listening on filename
1498 # ``\-d\*(Aq\*(Aq: argument will be taken as the target file descriptor for the
1500 # ``3\*(Aq\*(Aq : file descriptor\&. See ``A User\*(Aqs Guide to the Z\-Shell\*(Aq\*(Aq
1501 # (3\&.7\&.2: File descriptors)
1502 $ zmodload zsh/net/socket
1504 # ``\-a\*(Aq\*(Aq: accept an incoming connection to the socket
1505 $ zsocket \-a \-d 4 3
1506 $ zsocket \-a \-d 5 3 # accept a connection
1517 .nr an-no-space-flag 1
1521 \fBzsh/zftp (require zmodload zsh/zftp)\fR
1528 $ autoload \-U zfinit
1530 $ zfparams www\&.example\&.invalid myuserid mypassword
1533 $ zfls \-l zshtips\&.html
1534 $ zfput zshtips\&.html
1535 $ zfls \-l zshtips\&.html
1537 # Automatically transfer files using FTP with error checking
1538 $ autoload \-U zfinit ; zfinit
1539 $ zftp open host\&.name\&.invalid user passwd || exit
1540 $ zftp get /remote/file > /local/file; r=$?
1541 $ zftp close && exit r
1543 # compress and ftp on the fly
1544 $ autoload \-U zfinit ; zfinit
1545 $ zftp open host\&.name\&.invalid user password
1546 $ zftp get $file | bzip2 > ${file}\&.bz2
1549 # Recursice ``get\*(Aq\*(Aq
1550 $ autoload \-U zfinit ; zfinit
1551 $ zfanon cr\&.yp\&.to
1553 $ for file in `zfls` ; do
1558 # Upload all regular files in $HOME/foobar (recursive) that are newer than
1559 # two hours to ftp\&.foobar\&.invalid/path/to/upload
1560 $ autoload \-U zfinit ; zfinit
1561 $ zfopen ftp\&.foobar\&.invalid/path/to/upload
1563 $ zfput \-r **/*(\&.mh\-2)
1566 # long list of files on a ftp
1567 $ autoload \-U zfinit ; zfinit
1569 $ zfcd /some/remote/Dir
1570 $ cd /some/local/Dir
1571 # If the list\&.txt is located on the remote host, change to
1572 # zfget ${(f)"$(zftp get /path/to/remote/list\&.txt)"}
1573 $ zfget ${(f)"$(cat list\&.txt)"}
1582 .nr an-no-space-flag 1
1586 \fBzsh/zselect (require zmodload zsh/zselect)\fR
1593 # It\*(Aqs similar to
1596 | $ stty \-icanon min 0 time 50
1599 | $ case "$yesno" in
1604 $ zmodload zsh/zselect
1605 $ if zselect \-t 500 \-r 0 && read yesno && [ yes = "$yesno" ]; then
1616 .SS "Navigation options"
1618 \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\(cqt duplicate them)\&.
1621 \fBno_hup\fR (don\(cqt 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)
1624 .nr an-no-space-flag 1
1628 \fBHistory options\fR
1631 \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
1635 .nr an-no-space-flag 1
1639 \fBPrivacy / Security\fR
1642 \fBno_clobber\fR (or set \-C; prevent \fI>\fR redirection from truncating the given file if it already exists)
1646 .nr an-no-space-flag 1
1650 \fBSpelling correction\fR
1653 \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)
1657 Mailpath: simple multiple mailpath:
1663 mailpath=($HOME/Mail/mbox\*(Aq?new mail in mbox\*(Aq
1664 $HOME/Mail/tux\&.u\-strasbg\*(Aq?new mail in tux\*(Aq
1665 $HOME/Mail/lilo\*(Aq?new mail in lilo\*(Aq
1666 $HOME/Mail/ldap\-fr\*(Aq?new mail in ldap\-fr\*(Aq)
1672 Mailpath: dynamic mailpath:
1678 typeset \-a mailpath
1679 for i in ~/Mail/Lists/*(\&.); do
1680 mailpath[$#mailpath+1]="${i}?You have new mail in ${i:t}\&."
1687 Avoid globbing on special commands:
1693 for com in alias expr find mattrib mcopy mdir mdel which;
1694 alias $com="noglob $com"
1700 For migrating your bashprompt to zsh use the script bash2zshprompt located in the zsh source distribution under \fIMisc\fR\&.
1702 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\&.
1704 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:
1711 if [[ $TERM == "screen" ]]; then
1712 # Use these two for GNU Screen:
1713 print \-nR $\*(Aq 33k\*(Aq$1$\*(Aq 33\*(Aq\e
1714 print \-nR $\*(Aq 33]0;\*(Aq$2$\*(Aq\*(Aq
1715 elif [[ $TERM == "xterm" || $TERM == "rxvt" ]]; then
1716 # Use this one instead for XTerms:
1717 print \-nR $\*(Aq 33]0;\*(Aq$*$\*(Aq\*(Aq
1720 function precmd { title zsh "$PWD" }
1723 local \-a cmd; cmd=(${(z)1})
1724 title $cmd[1]:t "$cmd[2,\-1]"
1731 Put the following line into your ~/\&.screenrc to see this fancy hardstatus:
1737 caption always "%3n %t%? (%u)%?%?: %h%?"
1743 Special variables which are assigned:
1749 $LINENO $RANDOM $SECONDS $COLUMNS $HISTCHARS $UID
1750 $EUID $GID $EGID $USERNAME $fignore $mailpath $cdpath
1759 \fBhttp://www\&.zsh\&.org/\fR
1764 \fBhttp://sourceforge\&.net/projects/zsh/\fR
1767 Z shell page at sunsite\&.dk
1769 \fBhttp://zsh\&.sunsite\&.dk/\fR
1772 From Bash to Z Shell: Conquering the Command Line \- the book
1774 \fBhttp://www\&.bash2zsh\&.com/\fR
1777 "Zsh \- die magische Shell" (german book about Zsh) by Sven Guckes and Julius Plenz
1779 \fBhttp://zshbuch\&.org/\fR
1784 \fBhttp://www\&.zsh\&.org/mla/\fR
1789 \fBhttp://zsh\&.dotsrc\&.org/FAQ/\fR
1794 \fBhttp://zsh\&.sunsite\&.dk/Guide/\fR
1799 \fBhttp://zshwiki\&.org/home/\fR
1802 A short introduction from BYU
1804 \fBhttp://docs\&.cs\&.byu\&.edu/linux/advanced/zsh\&.html\fR
1809 \fBhttp://stchaz\&.free\&.fr/mouse\&.zsh\fR
1812 Curtains up: introducing the Z shell
1814 \fBhttp://www\-128\&.ibm\&.com/developerworks/linux/library/l\-z\&.html?dwzone=linux\fR
1817 ZSH\-Liebhaberseite (german)
1819 \fBhttp://michael\-prokop\&.at/computer/tools_zsh_liebhaber\&.html\fR
1822 ZSH\-Seite von Michael Prokop (german)
1824 \fBhttp://michael\-prokop\&.at/computer/tools_zsh\&.html\fR
1827 ZSH Prompt introduction
1829 \fBhttp://aperiodic\&.net/phil/prompt/\fR
1832 ft\(cqs zsh configuration
1834 \fBhttp://ft\&.bewatermyfriend\&.org/comp/zsh\&.html\fR
1839 \fBhttp://www\&.adamspiers\&.org/computing/zsh/\fR
1842 Zzappers Best of ZSH Tips
1844 \fBhttp://www\&.rayninfo\&.co\&.uk/tips/zshtips\&.html\fR
1847 Zsh Webpage by Christian Schneider
1849 \fBhttp://www\&.strcat\&.de/zsh/\fR
1852 The zsh\-lovers webpage
1854 \fBhttp://grml\&.org/zsh/\fR
1859 \fB#zsh at irc\&.freenode\&.org\fR
1862 The Z shell reference\-card (included in the zsh\-lovers debian\-package)
1864 \fBhttp://www\&.bash2zsh\&.com/zsh_refcard/refcard\&.pdf\fR
1868 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!
1870 In alphabetic order:
1876 Andrew \*(Aqzefram\*(Aq Main \- http://www\&.fysh\&.org/~zefram/
1877 Barton E\&. Schaefer \- http://www\&.well\&.com/user/barts/
1878 Matthias Kopfermann \- http://www\&.infodrom\&.north\&.de/~matthi/
1879 Oliver Kiddle \- http://people\&.freenet\&.de/opk/
1880 Paul Falstad \- http://www\&.falstad\&.com/
1881 Peter Stephenson \- http://homepage\&.ntlworld\&.com/p\&.w\&.stephenson/
1883 Stephane Chazelas \- http://stephane\&.chazelas\&.free\&.fr/
1884 Sven Guckes \- http://www\&.guckes\&.net/
1885 Sven Wischnowsky \- http://w9y\&.de/zsh/zshrc
1899 zshall Tthe Z shell meta\-man page
1900 zshbuiltins Zsh built\-in commands
1901 zshcalsys zsh calendar system
1902 zshcompctl zsh programmable completion
1903 zshcompsys Zsh completion system
1904 zshcompwid Zsh completion widgets
1905 zshcontrib User contributions to zsh
1906 zshexpn Zsh expansion and substitution
1907 zshmisc Anything not fitting into the other sections
1908 zshmodules Zsh loadable modules
1909 zshoptions Zsh options
1910 zshparam Zsh parameters
1911 zshroadmap Informal introduction to the zsh manual
1912 zshtcpsys Zsh tcp system
1913 zshzle Zsh command line editing
1914 zshzftpsys Zsh built\-in FTP client
1915 zshall Meta\-man page containing all of the above
1921 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\&.
1924 Probably\&. This manpage might be never complete\&. So please report bugs, feedback and suggestions to <zsh\-lovers@michael\-prokop\&.at>\&. Thank you!
1927 Copyright (C) Michael Prokop, Christian Schneider and Matthias Kopfermann\&.