zsh-workers, google, newsgroups and from ourself. See section *LINKS* for
details.
-Note: This manpage (zsh-lovers(1)) is *not* an offical part of the Z shell! It's
+Note: This manpage (zsh-lovers(1)) is *not* an official part of the Z shell! It's
just a just for fun - manpage ;) +
For comments, bugreports and feedback take a quick look at the section *BUGS*.
o_root=(-r WWW)
o_log=(-d ZWS.log)
- zparseopts -K -- p:=o_port r:=o_root h=o_help
+ zparseopts -K -- p:=o_port r:=o_root l:=o_log h=o_help
if [[ $? != 0 || "$o_help" != "" ]]; then
echo Usage: $(basename "$0") "[-p PORT] [-r DIRECTORY]"
exit 1
$ grep alias ~/.zsh/* C
443
----------------------
-Some more or less useful global aliases (choose whether they are useful or not
+Some more or less useful global aliases (choose whether they are useful or not
for you on your own):
--------------------------------------------------------
And if you want the number of errors allowed by _approximate to
increase with the length of what you have typed so far:
---------------------------------------------------------------------------------------------------
-zstyle -e ':completion:*:approximate:*' \
+zstyle -e ':completion:*:approximate:*' \
max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
If you end up using a directory as argument, this will remove the
-trailing slash (usefull in ln)
+trailing slash (useful in ln)
---------------------------------------------------------------------------------------------------
zstyle ':completion:*' squeeze-slashes true
---------------------------------------------------------------------------------------------------
zstyle ':completion:*:cd:*' ignore-parents parent pwd
---------------------------------------------------------------------------------------------------
+Another method for 'quick change directories'. Add this to your ~/.zshrc, then just enter
+``cd ..../dir''
+---------------------------------------------------------------------------------------------------
+rationalise-dot() {
+ if [[ $LBUFFER = *.. ]]; then
+ LBUFFER+=/..
+ else
+ LBUFFER+=.
+ fi
+}
+zle -N rationalise-dot
+bindkey . rationalise-dot
+---------------------------------------------------------------------------------------------------
+
UNSORTED/MISC examples
~~~~~~~~~~~~~~~~~~~~~~
Hint: A list of valid glob Qualifiers can be found in zshexpn(1).
See ``man 1 zshexpn | less -p'' Qualifiers for details.
-------------------------------------------------------------------------------
+# Get the names of all files that *don't* match a pattern *anywhere* on the
+# file (and without ``-L'' because its GNUish)
+ $ print -rl -- *(.^e{'grep -q pattern $REPLY'})
+ # or
+ $ : *(.e{'grep -q pattern $REPLY || print -r -- $REPLY'})
+
+# random numbers
+ $ echo $[${RANDOM}%1000] # random between 0-999
+ $ echo $[${RANDOM}%11+10] # random between 10-20
+ $ echo ${(l:3::0:)${RANDOM}} # N digits long (3 digits)
+
+# reverse a word
+ $ echo "${(j::)${(@Oa)${(s::):-hello}}}"
+
+# Show newest directory
+ $ ls -ld *(/om[1])
+
+# random array element
+ $ FILES=( .../files/* )
+ $ feh $FILES[$RANDOM%$#FILES+1]
+
+# cat first line in all files in this dir
+ $ for file (*(ND-.)) IFS= read -re < $file
+
# test if a parameter is numeric
$ if [[ $1 == <-> ]] ; then
echo numeric
fi
# Show me all the .c files for which there doesn't exist a .o file.
- $ c=(*.c) o=(*.o(N)) eval 'ls ${${c:#(${~${(j:|:)${o:r}}}).c}:?done}'
+ $ print *.c(e_'[[ ! -e $REPLY:r.o ]]'_)
# All files in /var/ that are not owned by root
$ ls -ld /var/*(^u:root)
# All files for which the owner hat read and execute permissions
$ echo *(f:u+rx:)
-# The same, but also others dont have execute permissions
+# The same, but also others don't have execute permissions
$ echo *(f:u+rx,o-x:)
# brace expansion - example
# Fetch the newest file containing the string 'fgractg*.log' in the
# filename and contains the string 'ORA-' in it
- $ file=(fgractg*.log(Nm0om[1]))
+ $ file=(fgractg*.log(Nm0om[1]))
$ (($#file)) && grep -l ORA- $file
# without Zsh
$ files=$( find . -name . -o -prune -name 'fgractg*>log' -mtime 0 -print )
- > if [ -n "$files" ]; then
- > IFS='
+ > if [ -n "$files" ]; then
+ > IFS='
> '
- > set -f
- > file=$(ls -td $files | head -1)
- > grep -l ORA- "$file"
+ > set -f
+ > file=$(ls -td $files | head -1)
+ > grep -l ORA- "$file"
> fi
# keep specified number of child processes running until entire task finished
$ zsh -c 'sleep 1 & sleep 3 & sleep 2& print -rl -- $jobtexts'
-
+
# Remove zero length and .bak files in a directory
$ rm -i *(.L0) *.bak(.)
-# print out files that dont have extensions
+# print out files that don't have extensions
$ printf '%s\n' ^?*.*
$ printf '%s\n' ^?*.[^.]*(D)
- $ ls -d -- ^?*.*(D)
+ $ ls -d -- ^?*.*(D)
# Finding files which does not contain a specific string
$ print -rl file* | comm -2 -3 - <(grep -l string file*)'
$ for f (file*(N)) grep -q string $f || print -r $f'
-# Show/Check whether a option is set or not. It works both with $options as
+# Show/Check whether a option is set or not. It works both with $options as
# with $builtins
$ echo $options[correct]
off
$ $options[zle]
on
-
+
# Count the number of directories on the stack
$ print $((${${(z)${(f)"$(dirs -v)"}[-1]}[1]} + 1)) # or
$ dirs -v | awk '{n=$1}END{print n+1}'
# Matching all files which do not have a dot in filename
$ ls *~*.*(.)
-
+
# Show only the ip-address from ``ifconfig device''
# ifconfig from net-tools (Linux)
- $ print ${${$(LC_ALL=C /sbin/ifconfig eth0)[7]}:gs/addr://}
+ $ print ${${$(LC_ALL=C /sbin/ifconfig eth0)[7]}:gs/addr://}
# ifconfig from 4.2BSD {Free,Net,Open}BSD
- $ print ${$(/sbin/ifconfig tun0)[6]}
+ $ print ${$(/sbin/ifconfig tun0)[6]}
-# Ping all the IP addresses in a couple of class C's or all hosts
+# Ping all the IP addresses in a couple of class C's or all hosts
# into /etc/hosts
$ for i in {1..254}; do ping -c 1 192.168.13.$i; done
or
: ping -c 1 $i ;
: echo '============================='
: done
-
+
# load all available modules at startup
$ typeset -U m
$ m=()
$ for md ($module_path) m=($m $md/**/*(*e:'REPLY=${REPLY#$md/}'::r))
$ zmodload -i $m
-# Rename all files within a directory such that their names get a numeral
+# Rename all files within a directory such that their names get a numeral
# prefix in the default sort order.
$ i=1; for j in *; do mv $j $i.$j; ((i++)); done
$ i=1; for f in *; do mv $f $(echo $i | \
awk '{ printf("%03d", $0)}').$f; ((i++)); done
$ integer i=0; for f in *; do mv $f $[i+=1].$f; done
-# Find (and print) all symbolic links without a target within the current
+# Find (and print) all symbolic links without a target within the current
# dirtree.
$ $ file **/*(D@) | fgrep broken
$ for i in **/*(D@); [[ -f $i || -d $i ]] || echo $i
# see above, but now omit executables
$ ls **/*~*(${~${(j/|/)fignore}})(.^*)
-# Print out files that dont have extensions (require *setopt extendedglob*
+# Print out files that don't have extensions (require *setopt extendedglob*
# and *setopt dotglob*)
$ printf '%s\n' ^?*.*
# Synonymic to ``ps ax | awk '{print $1}'''
$ print -l /proc/*/cwd(:h:t:s/self//)
-# Get the PID of a process (without ``ps'', ``sed'', ``pgrep'', ..
+# Get the PID of a process (without ``ps'', ``sed'', ``pgrep'', ..
# (under Linux)
$ pid2 () {
> local i
$ cd -- $dest_root
$ mkdir -p -- $dirs
# or without zsh
- $ find . -type d -exec env d="$dest_root" \
+ $ find . -type d -exec env d="$dest_root" \
sh -c ' exec mkdir -p -- "$d/$1"' '{}' '{}' \;
# If `foo=23'', then print with 10 digit with leading '0'.
$ foo=23
$ print ${(r:10::0:)foo}
-# find the name of all the files in their home directory that have
-# more than 20 characters in their file names
+# find the name of all the files in their home directory that have
+# 20 or more characters in their file names
print -rl $HOME/${(l:20::?:)~:-}*
# Save arrays
$ eval "m=($(cat -- $nameoffile)" # or use
$ m=("${(@Q)${(z)"$(cat -- $nameoffile)"}}") # to restore it
-# get a "ls -l" on all the files in the tree that are younger than a
-# specified age (e.g "ls -l" all the files in the tree that where
+# get a "ls -l" on all the files in the tree that are younger than a
+# specified age (e.g "ls -l" all the files in the tree that where
# modified in the last 2 days)
$ ls -tld **/*(m-2)
# This will give you a listing 1 file perl line (not à la ls -R).
# Convert images (foo.gif => foo.png):
$ for i in **/*.gif; convert $i $i:r.png
-# convert a collection of mp3 files to wave or cdr,
+# convert a collection of mp3 files to wave or cdr,
# e.g. file.wav -> file.mp3)
$ for i (./*.mp3){mpg321 --w - $i > ${i:r}.wav}
-
+
# Download with LaTeX2HTML created Files (for example the ZSH-Guide):
- $ for f in http://zsh.sunsite.dk/Guide/zshguide{,{01..08}}.html; do
+ $ for f in https://zsh.sourceforge.io/Guide/zshguide{,{01..08}}.html; do
> lynx -source $f >${f:t}
> done
-# Move all files in dir1 and dir2 that have line counts greater than 10 to
+# Move all files in dir1 and dir2 that have line counts greater than 10 to
# another directory say "/more10"
$ mv dir[12]/**/*.cr(-.e{'((`wc -l < $REPLY` > 10))'}) /more10
$ char=N ; print $((#char))
# Filename "Erweiterung"
-# Note: The (N) says to use the nullglob option for this particular
+# Note: The (N) says to use the nullglob option for this particular
# glob pattern.
$ for i in *.o(N); do
> rm $i
# gzip files when containing a certain string
$ gzip ${(ps:\0:)"$(grep -lZ foobar ./*.txt(.))"}
-# A small one-liner, that reads from stdin and prints to stdout the first
-# unique line i. e. does not print lines that have been printed before
-# (this is similar to the unique command, but unique can only handle
+# A small one-liner, that reads from stdin and prints to stdout the first
+# unique line i. e. does not print lines that have been printed before
+# (this is similar to the unique command, but unique can only handle
# adjacent lines).
$ IFS=$'\n\n'; print -rl -- ${(Oau)${(Oa)$(cat file;echo .)[1,-2]}}
(Recursive) Globbing - Examples
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A list of valid glob Qualifiers can be found in zshexpn(1). *Note:*
-\*\*/ is equivalent to (*/)#! For example:
+\*\*/ is equivalent to (*/)#! For example:
-------------------------------------------------------------------------------
$ print (*/)#zsh_us.ps
zsh-4.2.3/Doc/zsh_us.ps
# Search for `README' in all Subdirectories
$ ls -l **/README
-# find directories that contain both "index.php" and "index.html", or in
+# find directories that contain both "index.php" and "index.html", or in
# general, directories that contain more than one file matching "index.*"
$ ls **/*(D/e:'[[ -e $REPLY/index.php && -e $REPLY/index.html ]]':)
# or
$ find / | grep -e /path/ -e '/path$'
# Print he path of the directories holding the ten biggest C regular files
-# in the current directory and subdirectories.
- $ print -rl -- **/*.c(D.OL[1,10]:h) | sort -u
+# in the current directory and subdirectories.
+ $ print -rl -- **/*.c(D.OL[1,10]:h) | sort -u
# Find files with size == 0 and send a mail
- $ files=(**/*(ND.L0m+0m-2))
- > (( $#files > 0 )) && print -rl -- $files | \
+ $ files=(**/*(ND.L0m+0m-2))
+ > (( $#files > 0 )) && print -rl -- $files | \
mailx -s "empty files" foo@bar.tdl
# recursive chmod
$ list=(${1:[...]}/*(ND:t))
$ (($#list)) && print -rC2 -- ${(V)list}
-# Search all files in /home/*/*-mail/ with a setting ``chmod -s'' flag
-# (recursive, include dotfiles) remove the setgid/setuid flag and print
+# Search all files in /home/*/*-mail/ with a setting ``chmod -s'' flag
+# (recursive, include dotfiles) remove the setgid/setuid flag and print
# a message
$ chmod -s /home/*/*-mail(DNs,S) /home/*/*-mail/**/*(DNs,S))
# or with a small script
> print -r -- $file
> chmod -s $file && print -r fixed $file
> }
-# or use ``zargs'' (require autoload zargs) prevent the arg list too
+# or use ``zargs'' (require autoload zargs) prevent the arg list too
# long error
$ zargs /home/*/*-mail(DNs,S) /home/*/*-mail/**/*(DNs,S)) -- chmod -s
# List files beginning at `foo23' upwards (foo23, foo24, foo25, ..)
$ ls -l foo<23->
-# get all files that begin with the date strings from June 4 through
+# get all files that begin with the date strings from June 4 through
# June 9 of 2004
$ ls -l 200406{04..10}*(N)
# or if they are of the form 200406XX (require ``setopt extended_glob''
# List files in the current directory are not writable by the owner
$ print -l ~/*(ND.^w)
-# find and delete the files which are older than a given parameter
+# find and delete the files which are older than a given parameter
# (seconds/minutes/hours)
# deletes all regular file in /Dir that are older than 3 hours
$ rm -f /Dir/**/*(.mh+3)
$ rm ./**/*(.Dmh+1,.DL0)
# deletes all files more than 6 hours old
$ rm -f **/*(mh+6)
- # removes all files but the ten newer ones (delete all but last 10
+ # removes all files but the ten newer ones (delete all but last 10
# files in a directory)
$ rm ./*(Om[1,-11])
- Note: If you get a arg list too long, you use the builtin rm. For
+ Note: If you get a arg list too long, you use the builtin rm. For
example:
$ zmodload zsh/files ; rm -f **/*(mh+6)
or use the zargs function:
$ autoload zargs ; zargs **/*(mh+6) -- rm -f
-# A User's Guide to the Z-Shell /5.9: Filename Generation and Pattern
-# Matching find all files in all subdirectories, searching recursively,
-# which have a given name, case insensitive, are at least 50 KB large,
-# no more than a week old and owned by the root user, and allowing up
-# to a single error in the spelling of the name. In fact, the required
+# A User's Guide to the Z-Shell /5.9: Filename Generation and Pattern
+# Matching find all files in all subdirectories, searching recursively,
+# which have a given name, case insensitive, are at least 50 KB large,
+# no more than a week old and owned by the root user, and allowing up
+# to a single error in the spelling of the name. In fact, the required
# expression looks like this:
$ ls **/(#ia1)name(LK+50mw-1u0)
-
+
# Change the UID from 102 to 666
$ chown 666 **/*(u102)
# Show only empty files which nor `group' or `world writable'
$ ls *(L0f.go-w.)
-# find - and list - the ten newest files in directories and subdirs
+# Find - and list - the ten newest files in directories and subdirs.
# (recursive)
$ print -rl -- **/*(Dom[1,10])
-# Print only 5 lines by "ls" command (like ``ls -laS | head -n 5'')
+# Print only 5 lines by "ls" command (like ``ls -laS | head -n 5'').
$ ls -fl *(DOL[1,5])
-# display the 5-10 last modified files
+# Display the 5-10 last modified files.
$ print -rl -- /path/to/dir/**/*(D.om[5,10])
-
-# find all files without a valid owner
+
+# Find all files without a valid owner.
$ chmod someuser /**/*(D^u:${(j.:u:.)${(f)"$(</etc/passwd)"}%%:*}:)
-# find all the empty directories in a tree
+# Find all the empty directories in a tree.
$ for f in ***/*(/l2); do foo=($f/*(N)); [[ -z $foo ]] && print $f; done
# Note:Since Zsh 4.2.1 the glob qualifier F indicates a non-empty directory.
-# Hence *(F) indicates all subdirectories with entries, *(/^F) means all
+# Hence *(F) indicates all subdirectories with entries, *(/^F) means all
# subdirectories with no entries.
$ ls -ld *(/^F)
-# remove empty directories afterwards
+# Remove empty directories afterwards.
$ rmdir ./**/*(/od) 2> /dev/null
-# Show only files are owned from group `users'
+# Show only files which are owned by group `users'.
$ ls -l *(G[users])
-------------------------------------------------------------------------------
returned by parameter, filename and history expansion. See zshexpn(1)
for details.
-------------------------------------------------------------------------------
-# Remove a trailing pathname component, leaving the head. This works like
+# NOTE: Zsh 4.3.4 needed!
+ $ autoload -U age
+# files modified today
+ $ print *(e:age today now:)
+# files modified since 5 pm
+ $ print *(e-age 17:00 now-)
+# ... since 5 o'clock yesterda
+ $ print *(e-age yesterday,17:00 now-)
+# ... from last Christmas before today
+ $ print *(e-age 2006/12/25 today-)
+# ... before yesterday
+ $ print *(e-age 1970/01/01 yesterday-)
+# all files modified between the start of those dates
+ $ print *(e:age 2006/10/04 2006/10/09:)
+# all files modified on that date
+ $ print *(e:age 2006/10/04:)
+# Supply times.
+ $ print *(e-age 2006/10/04:10:15 2006/10/04:10:45-)
+
+# Remove a trailing pathname component, leaving the head. This works like
# `dirname'.
$ echo =ls(:h)
/bin
-# Remove all leading pathname components, leaving the tail. This works
+# Remove all leading pathname components, leaving the tail. This works
# like `basename'.
$ echo =ls(:t)
ls
$f:e is $f file extension
:h --> head (dirname)
:t --> tail (basename)
- :r --> rest (extension removed)
+ :r --> rest (extension removed)
$ for f (*.sh) mv $f $f:r
# Remove a filename extension of the form `.xxx', leaving the root name.
$ echo $foo:e
42
-# Print the new command but do not execute it. Only works with history
+# Print the new command but do not execute it. Only works with history
# expansion.
$ echo =ls(:h)
/bin
# convert 1st char of a word to uppercase
$ foo="one two three four"
- $ print -r -- "${(C)var}"
+ $ print -r -- "${(C)foo}"
One Two Three Four
-------------------------------------------------------------------------------
Redirection-Examples
~~~~~~~~~~~~~~~~~~~~
-See zshmisc(1) for more informations (or less ${^fpath}/zmv(N))
+See zshmisc(1) for more information (or less ${^fpath}/zmv(N))
-------------------------------------------------------------------------------
# Append `exit 1' at the end of all *.sh - files
# Redirect output to a file AND display on screen
$ foobar >&1 > file1 > file2 > ..
-
+
# pipe single output to multiple inputs
$ zcat foobar.Z >> (gzip -9 > file1.gz) \
>> (bzip2 -9 > file1.bz2) \
$ setopt multios
$ process1 > >(process1) > >(process2)
-# initializing a variable and simultaneously keeping terminal output
+# initializing a variable and simultaneously keeping terminal output
$ setopt multios
- $ { a=$(command >&1 >& 3 3 > &- 2>&1);} 3>&1
+ $ { a=$(command >&1 >& 3 3 > &- 2>&1);} 3>&1
# redirect stderr two times
$ setopt multios ; program 2> file2 > file1 2>&1
$ command 2>&2 2>stderr
# redirect stderr and stdout to separate files and both to orig. stdout:
$ command 2>&1 1>&1 2>stderr 1>stdout
-# redirect stderr and stdout to separate files and stdout to orig. stdout
+# redirect stderr and stdout to separate files and stdout to orig. stdout
# AND stderr to orig. stderr:
$ command 2>&2 1>&1 2>stderr 1>stdout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Note:* '-n' means no execution (just print what would happen). At
-------------------------------------------------------------------------------
+# Remove illegal characters in a fat32 file system. Illegal characters are
+# / : ; * ? " < > |
+# NOTE: ``-Q'' and (D) is to include hidden files.
+ $ unwanted='[:;*?\"<>|]'
+ $ zmv -Q "(**/)(*$~unwanted*)(D)" '$1${2//$~unwanted/}'
+
+# Changing part of a filename (i. e. "file-hell.name" -> "file-heaven.name")
+ $ zmv '(*)hell(*)' '${1}heaven${2}'
+ # or
+ $ zmv '*' '$f:s/hell/heaven/'
+
+# remove round bracket within filenames
+# i. e. foo-(bar).avi -> foo-bar.avi
+ $ zmv '*' '${f//[()]/}'
+
# serially all files (foo.foo > 1.foo, fnord.foo > 2.foo, ..)
$ autoload zmv
$ ls *
$ ls *
1.c 1.foo 2.foo 3.foo 4.foo foo.fnord
-# Rename "file.with.many.dots.txt" by substituting dots (exept for the last
+# Rename "file.with.many.dots.txt" by substituting dots (except for the last
# one!) with a space
$ touch {1..20}-file.with.many.dots.txt
$ zmv '(*.*)(.*)' '${1//./ }$2'
# Remove the first 4 chars from a filename
$ zmv -n '*' '$f[5,-1]' # NOTE: The "5" is NOT a mistake in writing!
-# Rename names of all files under the current Dir to lower case, but keep
-# dirnames as-is.
- $ zmv -Qv '(**/)(*)(.D)' '$1${(L)2}'
+# Rename names of all files under the current Dir to lower case, but keep
+# dirnames as-is.
+ $ zmv -Qv '(**/)(*)(.D)' '$1${(L)2}'
# replace all 4th character, which is "1", with "2" and so on
$ autoload -U zmv
$ touch 111111111111111{a-z}
$ autoload zmv
$ zmv '*' '$f[16,-1]'
-
+
# Replace spaces (any number of them) with a single dash in file names
$ autload zmv
- $ zmv -n '(**/)(* *)' '$1${2//( #-## #| ##)/-}'
+ $ zmv -n '(**/)(* *)' '$1${2//( #-## #| ##)/-}'
# or - with Bash
- $ find . -depth -name '* *' -exec bash -c '
- > shopt -s extglob
+ $ find . -depth -name '* *' -exec bash -c '
+ > shopt -s extglob
> file=$1
- > dir=${file%/*}
+ > dir=${file%/*}
> name=${file##*/}
> newname=${name//*([ -]) *([ -])/-}
- > mv -i -- "$file" "$Dir/$newname"' {} {} \;
+ > mv -i -- "$file" "$Dir/$newname"' {} {} \;
# Clean up file names and remove special characters
- $ autoload zmv
- $ zmv -n '(**/)(*)' '$1${2//[^A-Za-z0-9._]/_}'
+ $ autoload zmv
+ $ zmv -n '(**/)(*)' '$1${2//[^A-Za-z0-9._]/_}'
-# Add *.py to a bunch of python scripts in a directory (some of them end
+# Add *.py to a bunch of python scripts in a directory (some of them end
# in *.py and give them all a proper extension
- $ autoload zmv
+ $ autoload zmv
$ zmv -n '(**/)(con*)(#qe,file $REPLY | grep "python script",)' '$1$2.py'
# lowercase all extensions (i. e. *.JPG) incl. subfolders
- $ autoload zmv
+ $ autoload zmv
$ zmv '(**/)(*).(#i)jpg' '$1$2.jpg'
# Or - without Zsh
$ find Dir -name '*.[jJ][pP][gG]' -print | while read f
> done
# remove leading zeros from file extension
- $ autoload zmv
+ $ autoload zmv
$ ls
filename.001 filename.003 filename.005 filename.007 filename.009
filename.002 filename.004 filename.006 filename.008 filename.010
$ ls
filename.1 filename.10 filename.2 filename.3 filename.4 filename.5 ..
-# renumber files.
- $ autoload zmv
+# renumber files.
+ $ autoload zmv
$ ls *
foo_10.jpg foo_2.jpg foo_3.jpg foo_4.jpg foo_5.jpg foo_6.jpg ..
$ zmv -fQ 'foo_(<0->).jpg(.nOn)' 'foo_$(($1 + 1)).jpg'
$ ls *
foo_10.jpg foo_11.jpg foo_3.jpg foo_4.jpg foo_5.jpg ...
-# adding leading zeros to a filename (1.jpg -> 001.jpg, ..
- $ autoload zmv
+# adding leading zeros to a filename (1.jpg -> 001.jpg, ..
+ $ autoload zmv
$ zmv '(<1->).jpg' '${(l:3::0:)1}.jpg'
# See above, but now only files with a filename >= 30 chars
- $ autoload zmv
+ $ autoload zmv
$ c=1 zmv "${(l:30-4::?:)}*.foo" '$((c++)).foo'
# Replace spaces in filenames with a underline
- $ autoload zmv
+ $ autoload zmv
$ zmv '* *' '$f:gs/ /_'
# Change the suffix from *.sh to *.pl
- $ autoload zmv
+ $ autoload zmv
$ zmv -W '*.sh' '*.pl'
# Add a "".txt" extension to all the files within ${HOME}
# ``-.'' is to only rename regular files or symlinks to regular files,
# ``D'' is to also rename hidden files (dotfiles))
- $ autoload zmv
+ $ autoload zmv
$ zmv -Q '/home/**/*(D-.)' '$f.txt'
# Or to only rename files that don't have an extension:
$ zmv -Q '/home/**/^?*.*(D-.)' '$f.txt'
# Recursively change filenames with characters ? [ ] / = + < > ; : " , - *
- $ autoload zmv
+ $ autoload zmv
$ chars='[][?=+<>;",*-]'
$ zmv '(**/)(*)' '$1${2//$~chars/%}'
# Removing single quote from filenames (recursively)
- $ autoload zmv
+ $ autoload zmv
$ zmv -Q "(**/)(*'*)(D)" "\$1\${2//'/}"
-# When a new file arrives (named file.txt) rename all files in order to
-# get (e. g. file119.txt becomes file120.txt, file118.txt becomes
+# When a new file arrives (named file.txt) rename all files in order to
+# get (e. g. file119.txt becomes file120.txt, file118.txt becomes
# file119.txt and so on ending with file.txt becoming file1.txt
- $ autoload zmv
+ $ autoload zmv
$ zmv -fQ 'file([0-9]##).txt(On)' 'file$(($1 + 1)).txt'
# lowercase/uppercase all files/directories
- $ autoload zmv
+ $ autoload zmv
$ zmv '(*)' '${(L)1}' # lowercase
$ zmv '(*)' '${(U)1}' # uppercase
# Remove the suffix *.c from all C-Files
- $ autoload zmv
+ $ autoload zmv
$ zmv '(*).c' '$1'
# Uppercase only the first letter of all *.mp3 - files
- $ autoload zmv
+ $ autoload zmv
$ zmv '([a-z])(*).mp3' '${(C)1}$2.mp3'
# Copy the target `README' in same directory as each `Makefile'
- $ autoload zmv
+ $ autoload zmv
$ zmv -C '(**/)Makefile' '${1}README'
# Removing single quote from filenames (recursively)
- $ autoload zmv
+ $ autoload zmv
$ zmv -Q "(**/)(*'*)(D)" "\$1\${2//'/}"
# Rename pic1.jpg, pic2.jpg, .. to pic0001.jpg, pic0002.jpg, ..
- $ autoload zmv
+ $ autoload zmv
$ zmv 'pic(*).jpg' 'pic${(l:4::0:)1}.jpg'
$ zmv '(**/)pic(*).jpg' '$1/pic${(l:4::0:)2}.jpg' # recursively
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
# Copy files of a certain period (date indicated in the filenames)
- $ zmodload zsh/pcre
- $ ls -d -- *(e:'[[ $REPLY -pcre-match pcre-regexp ]]':)
+ $ zmodload zsh/pcre
+ $ ls -d -- *(e:'[[ $REPLY -pcre-match pcre-regexp ]]':)
# or
$ m() { [[ $1 -pcre-match pcre-regexp ]] }
$ ls -d -- *(+m)
zsh/clone (require zmodload zsh/clone)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-------------------------------------------------------------------------------
-# Creates a forked instance of the current shell ($! is set to zero) and
+# Creates a forked instance of the current shell ($! is set to zero) and
# execute ``command'' on /dev/tty8 (for this example).
$ zmodload zsh/clone
$ clone /dev/tty8 && (($! == 0)) && exec command
$ $ zmodload zsh/datetime
$ setopt extendedglob
$ touch aaa_bbb_20041212_c.dat eee_fff_20051019_g.dat
- $ strftime -s pattern \
+ $ strftime -s pattern \
'???_???_<0-%Y%m%d>_?.dat' $((EPOCHSECONDS - 365 * 24 * 60 * 60 / 2))
$ print -rl -- $~pattern
aaa_bbb_20041212_c.dat
- $ print -rl -- $pattern
+ $ print -rl -- $pattern
???_???_<0-20050815>_?.dat
-# Search files size == 0, to be based on the file name containing a date
+# Search files size == 0, to be based on the file name containing a date
# rather than the "last modified" date of the file
- $ zmodload -i zsh/datetime
- $ strftime -s file "abc_de_%m%d%Y.dat" $((EPOCHSECONDS - 24 * 60 * 60 ))
- $ files=(**/$file(N.L0))
- $ (( $#files > 0 )) && print -rl -- $files | \
- mailx -s "empty files" foo@bar.tdl
+ $ zmodload -i zsh/datetime
+ $ strftime -s file "abc_de_%m%d%Y.dat" $((EPOCHSECONDS - 24 * 60 * 60 ))
+ $ files=(**/$file(N.L0))
+ $ (( $#files > 0 )) && print -rl -- $files | \
+ mailx -s "empty files" foo@bar.tdl
-------------------------------------------------------------------------------
zsh/stat (require zmodload zsh/stat)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-------------------------------------------------------------------------------
+# test if a symbolic link links to a certain file
+ $ zmodload -i zsh/stat
+ $ ! stat -LH s foo.ln || [[ $s[link] != "foo.exe" ]] || ln -sf foo.exe foo.ln
+
# comparing file dates
$ zmodload zsh/stat
$ file1=foo
$ file2=bar
$ touch bar & sleep 5 & touch foo
- $ echo $file1 is $(($(stat +mtime $file2) - \
+ $ echo $file1 is $(($(stat +mtime $file2) - \
$(stat +mtime $file1))) seconds older than $file2.
bar is 5 seconds older than foo
$ zmodload zsh/stat
$ ls -fld ./**/*(d`stat +device .`OL[1,100])
-# Get only the user name and the file names from (like
+# Get only the user name and the file names from (like
# ls -l * | awk '{print $3" " $8}')
$ zmodload zsh/stat
$ for file; do
# ``[1]'': return only first one
$ zmodload zsh/stat
$ stat +size ./*(DOL[1])
-
+
# file size in bytes
$ zmodload zsh/stat
$ stat -L +size ~/.zshrc
4707
# Delete files in a directory that hasn't been accessed in the last ten days
-# and send ONE mail to the owner of the files informing him/her of the files'
+# and send ONE mail to the owner of the files informing him/her of the files'
# deletion.
$ zmodload zsh/stat zsh/files
$ typeset -A f; f=()
$ rm -f /path/**/*(.a+10e{'stat -sA u +uidr $REPLY; f[$u]="$f[$u]$REPLY"'})
$ for user (${(k)f}) {print -rn $f[$user]|mailx -s "..." $user}
-# Get a "ls -l" on all the files in the tree that are younger than a
+# Get a "ls -l" on all the files in the tree that are younger than a
# specified age
$ zmodload zsh/stat
$ for d (. ./**/*(N/m-2))
$ stat -F '%d %m %Y' +mtime ~/.zshrc
30 06 2004
$ stat -F '%D' +mtime ~/.zshrc
- 06/30/04
+ 06/30/04
-------------------------------------------------------------------------------
zsh/files (require zmodload zsh/files)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-------------------------------------------------------------------------------
-# search a directory for files containing a certain string then copy those
+# search a directory for files containing a certain string then copy those
# files to another directory.
$ zmodload zsh/files
$ IFS=$'\0'
$ zmodload zsh/mapfile
$ pattern1="foo"
$ pattern2="bar foo"
- $ print -l ./**/*(DN.e{'z=$mapfile[$REPLY] && [[ $z = *$pattern1* && \
+ $ print -l ./**/*(DN.e{'z=$mapfile[$REPLY] && [[ $z = *$pattern1* && \
$z = *$pattern2* ]]'})
# or a solution in combination with zsh/pcre
$ zmodload -i zsh/mapfile zsh/pcre
# or - for case insensitive
$ setopt extendedglob
$ print -rl -- ${${=mapfile[/etc/passwd]}:#*(#i)root*}
-
-# If a XML-file contains stuff like ``<TAGA/>'' and ``<TAGB/>'', number
-# this empty tags (ones ending in '/>') so if encountered in the same
-# order, the preceeding tags would become ``<TAGA/>1</TAGA>'' and
+
+# If a XML-file contains stuff like ``<TAGA/>'' and ``<TAGB/>'', number
+# this empty tags (ones ending in '/>') so if encountered in the same
+# order, the preceding tags would become ``<TAGA/>1</TAGA>'' and
# ``<TAGB/>2</TAGB>''
$ zmodload zsh/mapfile
$ cnt=0
# removing all files in users Maildir/new that contain ``filename="gone.src''
$ zmodload zsh/{files,mapfile}
- $ rm -f /u1/??/*/Maildir/new/100*(.e{'[[ $mapfile[$REPLY] == \
+ $ rm -f /u1/??/*/Maildir/new/100*(.e{'[[ $mapfile[$REPLY] == \
*filename=\"gone.scr\"* ]]'})
-# Grep out the Title from a postscript file and append that value to the
+# Grep out the Title from a postscript file and append that value to the
# end of the filename
$ autoload -U zmv
$ zmodload zsh/mapfile
$ zmodload zsh/mathfunc
$ echo $(( sin(1/4.0)**2 + cos(1/4.0)**2 - 1 ))
-1.1102230246251565e-16
-$ echo $(( pi = 4.0 * atan(1.0) ))
+$ echo $(( pi = 4.0 * atan(1.0) ))
3.1415926535897931
$ echo $(( f = sin(0.3) ))
0.29552020666133955
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-------------------------------------------------------------------------------
$ autoload -U zfinit
- $ zfinit
+ $ zfinit
$ zfparams www.example.invalid myuserid mypassword
- $ zfopen
+ $ zfopen
$ zfcd tips
$ zfls -l zshtips.html
$ zfput zshtips.html
> zfget $file
$ done
$ zfclose
-
-# Upload all regular files in $HOME/foobar (recursive) that are newer than
+
+# Upload all regular files in $HOME/foobar (recursive) that are newer than
# two hours to ftp.foobar.invalid/path/to/upload
$ autoload -U zfinit ; zfinit
$ zfopen ftp.foobar.invalid/path/to/upload
$ cd $HOME/foobar
$ zfput -r **/*(.mh-2)
$ zfclose
-
+
# long list of files on a ftp
$ autoload -U zfinit ; zfinit
$ zfopen some-host
Special variables which are assigned:
------------------------------------------------------
-$LINENO $RANDOM $SECONDS $COLUMNS $HISTCHARS $UID
+$LINENO $RANDOM $SECONDS $COLUMNS $HISTCHARS $UID
$EUID $GID $EGID $USERNAME $fignore $mailpath $cdpath
------------------------------------------------------
LINKS
-----
Primary site::
- *http://www.zsh.org/[]*
+ *http://www.zsh.org/[]*
+Zsh Web Pages::
+ *https://zsh.sourceforge.io/[]*
Project-page::
- *http://sourceforge.net/projects/zsh/[]*
-Z shell page at sunsite.dk::
- *http://zsh.sunsite.dk/[]*
+ *http://sourceforge.net/projects/zsh/[]*
From Bash to Z Shell: Conquering the Command Line - the book::
*http://www.bash2zsh.com/[]*
+"Zsh - die magische Shell" (german book about Zsh) by Sven Guckes and Julius Plenz::
+ *http://zshbuch.org/[]*
Mailinglistarchive::
*http://www.zsh.org/mla/[]*
ZSH-FAQ::
- *http://www.zsh.org/FAQ/[]*
+ *https://zsh.sourceforge.io/FAQ/zshfaq.html[]*
Userguide::
- *http://zsh.sunsite.dk/Guide/[]*
+ *https://zsh.sourceforge.io/Guide/[]*
ZSH-Wiki::
- *http://www.zshwiki.org/[]*
-Die Zsh als interaktive Shell::
- *http://cssun.rrze.uni-erlangen.de/~sipakale/zshreferat.html[]*
-A short introduction from BYU::
- *http://docs.cs.byu.edu/docs/zsh/index.php[]*
+ *http://zshwiki.org/home/[]*
Mouse-Support ;)::
*http://stchaz.free.fr/mouse.zsh[]*
-Shell Corner: Zsh Suite of "keeper" Functions::
- *http://www.unixreview.com/documents/s=9513/ur0501a/ur0501a.htm[]*
-The Z Shell (A Fan Page)::
- *http://www.princeton.edu/~kmccarty/zsh.html[]*
-Making the Transition to Zsh::
- *http://www.linux-mag.com/cgi-bin/printer.pl?issue=2002-05&article=power[]*
-Curtains up: introducing the Z shell::
- *http://www-128.ibm.com/developerworks/linux/library/l-z.html?dwzone=linux[]*
-ZSH-Liebhaberseite::
- *http://michael-prokop.at/computer/tools_zsh_liebhaber.html[]*
-ZSH-Seite von Michael Prokop::
- *http://www.michael-prokop.at/computer/tools_zsh.html[]*
-A Case for the Z Shell on *http://www.daemonnews.org/[]*::
- *http://ezine.daemonnews.org/199910/zsh.html[]*
-ZSH-Section from Dotfiles.com::
- *http://www.dotfiles.com/index.php?app_id=4[]*
-Writing Zsh Completion Functions::
- *http://www.linux-mag.com/2002-07/power_01.html[]*
ZSH Prompt introduction::
*http://aperiodic.net/phil/prompt/[]*
+ft's zsh configuration::
+ *http://ft.bewatermyfriend.org/computer/zsh.html[]*
Adam's ZSH page::
*http://www.adamspiers.org/computing/zsh/[]*
Zzappers Best of ZSH Tips::
*http://www.rayninfo.co.uk/tips/zshtips.html[]*
Zsh Webpage by Christian Schneider::
- *http://strcat.de/wiki/zsh/[]*
- *http://strcat.de/wiki/zsh-german[]* (German translation. Help needed!)
+ *http://www.strcat.de/zsh/[]*
The zsh-lovers webpage::
*http://grml.org/zsh/[]*
IRC channel::
-------------------------------------------------------------------------
Andrew 'zefram' Main - http://www.fysh.org/~zefram/
Barton E. Schaefer - http://www.well.com/user/barts/
-Matthias Kopfermann - http://www.infodrom.north.de/~matthi/
+Matthias Kopfermann - http://www.guckes.net/zsh/lover.html
Oliver Kiddle - http://people.freenet.de/opk/
Paul Falstad - http://www.falstad.com/
Peter Stephenson - http://homepage.ntlworld.com/p.w.stephenson/
Richard Coleman
Stephane Chazelas - http://stephane.chazelas.free.fr/
Sven Guckes - http://www.guckes.net/
-Sven Wischnowsky - http://w9y.de/zsh/zshrc
+Sven Wischnowsky - http://w9y.de/
-------------------------------------------------------------------------
SEE ALSO
--------
Manpages of zsh:
------------------------------------------------------------------
- zsh Zsh overview
+ zsh Zsh overview
zshall Tthe Z shell meta-man page
zshbuiltins Zsh built-in commands
- zshcompctl Zsh completion control
+ zshcalsys zsh calendar system
+ zshcompctl zsh programmable completion
zshcompsys Zsh completion system
zshcompwid Zsh completion widgets
zshcontrib User contributions to zsh
BUGS
----
-Probably. This manpage might be never complete. So please report bugs,
-feedback and suggestions to <zsh-lovers@michael-prokop.at>. Thank
-you!
+Probably. This manpage might be never complete.
+So please report bugs, feedback and suggestions via https://github.com/grml/zsh-lovers
+Thank you!
COPYRIGHT
---------