🖥️zsh

➡️This is a command-line reference manual for commands and command combinations that you don’t use often enough to remember it. This cheatsheet explains the zsh command with important options and switches using examples.

▁ ▂ ▃ ▄ ꧁ 🔴☠ COMMANDLINE-KUNGFU WITH CHEATSHEETS ☠🔴꧂▅ ▃ ▂ ▁

#                ███████╗███████╗██╗  ██╗
#                ╚══███╔╝██╔════╝██║  ██║
#                  ███╔╝ ███████╗███████║
#                 ███╔╝  ╚════██║██╔══██║
#                ███████╗███████║██║  ██║
#                ╚══════╝╚══════╝╚═╝  ╚═╝
                                        
                                                                                           

# ZSH Tips 
#-----------------------#

zsh -f   # start a "clean" version of zsh (without your startup files)
print $ZSH_VERSION

man zsh
man zshall

man zsh          Zsh overview
man zshmisc      Anything not fitting into the other sections
man zshexpn      Zsh command and parameter expansion
man zshparam     Zsh parameters
man zshoptions   Zsh options
man zshbuiltins  Zsh built-in functions
man zshzle       Zsh command line editing
man zshcompwid   Zsh completion widgets
man zshcompsys   Zsh completion system
man zshcompctl   Zsh completion control
man zshmodules   Zsh loadable modules
man zshzftpsys   Zsh built-in FTP client
man zshall       Meta-man page containing all of the above info --index-search=age zsh         

# get man info for zsh function age *N*
zinfo(){info --index-search=$1 zsh} *N*

/usr/share/zsh/htmldoc/zsh_toc.html

# Install on Linux
yum install zsh *N*
yum update zsh *N*

# install from source
wget --no-check-certificate https://sourceforge.net/projects/zsh/files/zsh/5.4.2/zsh-5.4.2.tar.gz
tar zxvf zsh-5.4.2.tar.gz
yum install gcc ncurses-devel # if required
cd zsh-5.4.2 && ./configure && make && sudo make install

# Global aliases
# Searching and filtering my mysql database with my own utility searchdb
searchdb client1 | grep -i website1 | fmt -50 | putclip

# How you can simplify this using 3 zsh Global Aliases
searchdb client1 G website1 F P

alias -g ND='*(/om[1])' # newest directory
alias -g NF='*(.om[1])' # newest file

#Example of use
cp NF ND          # copy newest file to newest directory
cat NF > $(print NF).txt # *N*

# useful zsh stuff *N*
ls *(.)           # list just regular files *N*
ls -d *(/)           # list just directories *C*
ls *(.[3])        # third file *N*
vi *(.om[1])      # vi newest file
cd **/*.php(.om[1]:h) # cd to directory of newest php file *N*
gvim.exe *~vssver.scc(.om[1]) & # newest file ignoring any vssver.scc
vi -p *(.om[1,3]) # open 3 newest files in tabs (gvim)
ls -lt  **/*(.om[1,20]) # list 20 newest files anywhere in directory hierarchy (very useful) *N*
ls -lt  **/*.php(.om[1,20]) # list 20 newest php files anywhere in directory hierarchy (very useful) *N*
grep -i "$1" **/*.{js,php,css}~(libs|temp|tmp|test)/* # exclude directories from grep *N* EXTENDED_GLOB required
ls -lt **/*~*vssver.scc(.om[1,20])  # excluding vssver.scc *N*
ls -lt **/^vssver.scc(.om[1,20])    #  excluding vssver.scc (simpler) *N*
ls -lt **/^(vssver.scc|*.ini)(.om[1,20]) # excluding vssver and any *.ini *N*
ls *(.)^php~*.c~*.txt   # useful? *N*
ls (../)#junk2/down.txt(:a)   # locate a file "upwards" *N*
vi *(m0)          # re-edit all files changed today!
ls *(^m0)         # files NOT modified today
ls -l *(m4)       # list files modified exactly 4 days ago
ls -l *(.m4)      # list files modified exactly 4 days ago (ignore directories)
vi **/main.php    # where ever it is in hierarchy
ls -l **/main.{php,js,css}    #    *N*
ls fred^erick*    # list all files fred* except frederick*    *N*
ls *.^pdf         # list all but pdf's *NN*
ls (x*~x[3-5])    # list files x* except x3 to x5
ls x^[3-5]*       # list files x* except x3 to x5 *N*
ls **/*~*/.git/*  # ignore all git subdirectories *~* matches a path *N*
vi !$             # vi last parameter
vi !-2:2          # second parameter of second but last command
vi !$:r.php       # vi last parameter but change extension to .php
^php^cfm          # modify previous command (good for correcting spellos)
ls *(.L0)         # list pesky empty files (yes that is a zero) *N*
ls -l *(L-2)      # list file size less than 2 bytes *N*
ls -l *(.L-20)    # list file size less than 20 bytes - . ignore directories *N*

# zsh list largest / biggest files , files larger than
ls -l *(Lk+100)   # list file size larger/greater than 100kb *N*
ls -l *(Lm+2)     # list file size larger/greater than 2 mbs *N*
ls **/*(.Lm+10)   # list files larger than 10MB anywhere in hierarchy *N*
ls -hlS **/*(.Lm+2)  | less  # list largest files  largest first  *N*
ls -hlS /**/*(.OL[1,10]) # find the 10 biggest files on your system *N*

# find 5 largest files in hierarchy with filter by file type & exclude directories
ls -lS **/*.(php|inc)~(libs|locallibs)/*(.OL[1,5]) # *N*
ls *(.m0)  # modified today (last 24 hours)
ls *(.m-1)  # modified today (last 24 hours)
ls *(.^m0)  # not modified today
ls *.*(m3)  # modified 3 days ago
ls *.*(mh3)  # modified 3 hours ago
ls *.*(mh-3) # less than 3 hours
ls *.*(mh+3) # more than 3 hours
ls *.*(^mh3) # all files not 3 hours  old
mv *(.mw+2) old/ # older than 2 weeks *N*
mv *(.mM+6) old/ # older than 6 months *N*

# counts requires extended globbing *N*
setopt EXTENDED_GLOB   # lots of clever stuff requires this
ls DATA_[0-9](#c3).csv  # match all files DATA_nnn.csv  *N*
ls a(#c3).txt     # match aaa.txt   *N*
ls DATA_[0-9](#c4,7).csv  # match DATA_nnnn.csv to DATA_nnnnnnn.txt *N*
ls DATA_[0-9](#c4,).csv  # match DATA_nnnn.csv to DATA_nnnnn.txt etc *N*
ls DATA_[0-9](#c,4).csv  # match DATA_n.csv to DATA_nnn.txt *N*
touch {1..5} {6,7,8,12} {00..03} # *N*
ls <-> <-6> <4-> <4-5> 0<-> {1..5} {2,3} {00..03} (4|5) [3-4]  [3-47-8] 0? ?2 *2 # *N*
ls {p..q}<5->{1..4}.(#I)php(.N)  # *N*
touch {y,y2}.cfm
ls y2#.cfm y{2,}.cfm y(2|).cfm {y2,y}.cfm (y|y2).cfm y*.cfm # *N*
touch {t,p}{01..99}.{php,html,c}  # generate 600 test files *N*
#
grep -i "$1" */*.php~libs/*~temp/*~test/* # exclude directories lib,temp,test from grep *N* EXTENDED_GLOB required

# file ownership/permissions
ls -ld *.*(u:apache:)

# excluding files a-m but only if owned by apache
-rwxr-xr-x. 1 nobody (owner) apache (Group) 0 Feb 24 10:23 x.x
ls -l *.*~[a-m]*(u:nobody:g:apache:.xX)

# find all files owned by root (u0), world-writable (W), more than 10k in size (Lk+10) and modified during the last hour (m0)
ls **/*(u0WLk+10m0)

# find all files that don’t have the write permission to group in current directory and all subdirectories
ls **/*(.:g-w:)

# grep
grep -i "$1" **/*.{js,php,css}~(libs|temp|temp|test)/* # exclude directories from grep *N* EXTENDED_GLOB required
grep -iw '$direct' report/**/*.{inc,php}  # searching for a php variable

#  deleting  double dot files & swap files *N*
rm **/.*.swp

# use tab to complete/display history item before executing
!1 # oldest command in your history
!! # previous command
!-2 # command before last
!$ (last argument of previous command)
!$:h (last argument, strip one level)
!$:h:h (last argument, strip two levels)
!?echo
echo !* !!:* (all parameters)
echo !$ !!:$ (last parameter)
echo !^ !:1 !!:1 (first previous parameter)
echo !:2-3   # echo previous parameters 2 to 3 *N*
echo !:2*    # echo previous parameters 2 onwards  *N*
echo !:2-    # echo previous parameters 2 onwards omitting last *N*
echo !:-3    # echo first 3 previous parameters
echo !-2:2 (second parameter of second but last command)
echo convert_csv.php(:a) # echo full path *N*

touch 1 2 3    # *N*
!!:0 !^ !:2 !$ !#$ !#:2 !#1 !#0   #  *U*

history               # View recent commands

# history has built-in search (match) *N*
history -m 'yum*'
history -m 'yum*' 0
fc -l  -m 'yum*' 0
!42                   # Re-execute history command 42

# substitute previous command
r oldstr=newstr
!!:s/fred/joe/        # edit previous command replace first fred by joe
!!:s/fred/joe/        # Note : sadly no regexp available with :s///
!!:gs/fred/joe/       # edit previous command replace all fred by joe
mv Licence\ to\ Print\ Money.pdf !#^:gs/\\ //  # rename file removing spaces
^fred^joe             # edit previous command replace fred by joe
^str1^str2^:u:p       # replace str1 by str2 change case and just display
echo chim
^chim^&-&ney-&-&-cheree # reuse LHS
!42:p
also use control-R
^str1^str2^:G         # replace as many as possible

# in all of above remember <TAB> will display changed command WITHOUT executing it *N*

cd !?ls<TAB>   #get command and parameters of a previous ls command
cd !?ls?:*<TAB>   #get (just) parameters of a previous ls command
function scd(){setopt nonomatch;e=/dev/null;cd $1 &> $e||cd ${1}* &> $e||cd *$1 &> $e||cd *${1}* &> $e||echo sorry} *N*
function ddump(){diff -w ~dump/"$1" "$1"}   # *N* diff local file with new one in dump
function cdump(){cp -p ~dump/"$1" "$1"}   # *N* replace local file with new one in dump

# Generating a command from an earlier one
# How to recall the parameters of a previous command, on line 7 below recall the parameters of line 5

5> mv somefile1 /home/saket/stuff/books/
6> acroread somefile.pdf
7> mv somefile2 /home/saket/stuff/books/

> mv !?saket<TAB>
# Would bring up the whole line ready for a little editing
    # or purist
> mv !?saket?:*<tab>
# Would just bring up the parameters

# If you know the history number of the line (say 5) with desired parameters you can try
> !5:s/somefile1/somefile2/

# and if you dont know the history number
!?saket?:s/somefile1/somefile2/

# Variable Substitution *N*
s=(fred joe peter);echo ${s/(#m)*/$MATCH[1,3]} # truncate strings in an array

# History Substitution Summary
# For CURRENT line that you are editing (the # designates current line)
# Remember Tab will expand the following

!#:0    command
!#^     first parameter
!#:1    first parameter
!#:1-4  first 4 parameters
!#$     last parameter
!#*     all parameters
!#$:s/bash/zsh perform substitution on previous parameter

# backup a file with a prefix
cp longfilename.php backup_!#^
cp {,backup_}longfilename.php   # same thing

# backup a file with a suffix
cp longfilename.php !#^:r.bak
cp longfilename.{php,bak}   # expands to cp longfilename.php longfilename.bak

#For Previous Command (for comparison)
!-1     repeat whole command
!!      repeat (shortcut)
!!0     command
!^      first parameter
!:1     first parameter
!:1-4   first 4 parameters
!:-4  !:0-4  first 4 parameters plus command
!!-     all but last parameter *N*
!51$    last parameter of history entry 51 *N*
!$      last parameter
!*      all parameters
!!:s/bash/zsh (or ^bash^zsh)
!^:t    just file name of first parameter
!$:h    just path of last parameter
!-2$:r  just file name without extension of first parameter

For last but one command
!-2     repeat last but one command
!-2^    first parameter last but one command
!-2$    last parameter last but one command
!-2:2   second parameter of second but last command
!-2:s/bash/zsh
etc
For history command 42
!42

!:0 is the previous command name
!^, !:2, !:3, !$ are the arguments
!* is all the arguments
!-2, !-3,  are earlier commands
!-2^, !-2:2, !-2$, !-2* are earlier parameters

ls /                  # recall/step through previous parameters *N*
fred='/bin/path/fred.txt'
echo ${fred:e}
echo ${fred:t}
echo ${fred:r}
echo ${fred:h}
echo ${fred:h:h}
echo ${fred:t:r}
cd !$:h  (remove file name)

# cd to directory containing report.php
cd **/report.php(:h) *N*
cat !!:t (only file name)

# Convert images (foo.gif => foo.jpg):
$ for i in **/*.gif; convert $i $i:r.jpg

# examples of if then else conditionals *N*
[[ 0 = 0 ]] && echo eq || echo neq
[[ 1 = 0 ]] && echo eq || echo neq
if [ $# -gt 0 ];then string=$*;else;string=$(getclip);fi # get parameter OR paste buffer
var=133;if [[ "$var" = <-> ]] ; then echo "$var is numeric" ;fi
if [[ "$ip" = <-> ]] then # check ip address numeric *N*
if [[ "$1" == [0-9] ]]  # if $1 is a digit
if (( $# == 0 ));
if [ $# -gt 0 ]  # parameter cnt > 0 (arguments)
if [[ "$url" = www* ]] # begins with www
if [ "$p1" = "end" ] || [ "$p1" = "-e" ]
if [[ "$p2" == *[a-zA-Z][a-zA-Z][a-zA-Z]* ]]  # contains at least 3 letters
if builtin cd $1 &> /dev/null ;
if [[ -e /c/aam/z$1 ]]  # file exists
if [ $cnt -eq 1 ]
if (( ${#dirs} == 1 )); then   # count array length
if [[ "$pwd" == *$site2* ]]

print ${param:&}   (last substitute)

< readme.txt  # < shorthand for more

# Directory substitution (magic)
# if you were in directory
# cd old new
/c/inetpub/dev.somehomes.co.uk/epsystem/eppigeon/
cd dev www

#would put you in parallel directory
/c/inetpub/www.somehomes.co.uk/epsystem/eppigeon/

# completion
cd /v/w/h/<tab>

# expand to
# cd /var/www/html/

# filtering the output of a command conventionally
print $(history -n -1|sed 's/.* //')

# ${${(z)foo}[2]} zsh filtering mechanism
print ${${(z)$(history -n -1)}[-1]}
print ${${(z)history[$((HISTCMD-1))]}[-1]}
gvim.exe $(history -n -1 | sed "s/^[^ ]* //;s/ .*//")
print ${${(z)history[$((HISTCMD-1))]}[2]}
# save last 4 history items to a file (without numbers) *N*
fc -ln -4 > /tmp/hist   # no numbers
fc -ln 1 | grep rsync | gvim -
fc -l -5     # 5 most recent *N*
fc -l 1 5   # 5 oldest *N*
fc -l -10 -5  # 10th newest to 5 newest *N*
fc -l 1 | more  # step through all history *N*

# ls
ls **/*.php
ls -ld *(/^F)  # list any empty sub-directories
ls -ld **/*(/^F) # recursively list any empty sub-directories
print **/*(/^F) | xargs -n1 -t rmdir #delete empty directories
rmdir ./**/*(/od) 2> /dev/null # deletes empty directories
autoload zargs;zargs ./**/*.{php,inc,js} -- grep -i 'cons. unit'   *N* EXTENDED_GLOB
zargs **/*.{js,php,css}~(libs|locallibs|test|dompdf)/* -- grep console.log *C* EXTENDED_GLOB
zargs ./**/*.(php|inc|js) -- tar rvf dev2$(date '+%d-%m-%Y').tar *N*
# grep whole file structure for php files with if ($var=4) (single equals) bug
zargs ./**/*.{inc,php} -- grep -i 'if *( *$[a-z0-9_]*=[0-9"]'   ## detect if ($fred=2) type php errors (single equals) *N*
# selectively tar a web root *N*
zargs ./{html,live}/**/*.(php|inc|js)~(**/wiki|**/dompdf)/* -- tar rvf /tmp/web2$(date "+%d-%m-%Y").tar
zargs **/*.(php|inc) -- sed -i 's#ereg_replace("\([^"]*\)"#preg_replace("/\1/"#g'    ## global sed substitute using zargs *N*
zargs  /tmp/*(.m+30) -- rm
ls ^x*           # list all but x*
#list all files without an extension ( no dot)
a=(**/*(.D));echo $#a  # count files in a (huge) hierarchy *N*
ls *~*.*(.)
# delete all directories Pictures_of_* except Pictures_of_beautiful_flowers
rm -rf Pictures_of_^beautiful_flowers   # selective delete *N*
ls x*~(x3|x5)    # list files x* except x3 and x5
ls **/fred*~*junk*/* # list all files fred* unless in a junk directory
# grep, dont use egrep, grep -E is better

# single quotes stop the shell, " quotes allow shell interaction
grep 'host' **/(*.cfm~(ctpigeonbot|env).cfm)
grep -i 'host' **/(*.cfm~(ctpigeonbot|env).cfm)~*((#s)|/)junk*/*(.)
egrep -i "^ *mail\(" **/*.php
grep "^ *mail\(" **/*.php~*junk*/*  #find all calls to mail, ignoring junk directories
# grep '.' dot matches one character
grep b.g file    # match bag big bog but not boog
# grep * matches 0 , 1 or many of previous character
grep "b*g" file # matches g or bg or bbbbg
# grep '.*' matches a string
grep "b.*g" file # matches bg bag bhhg bqqqqqg etc
# grep break character is \
grep 'hello\.gif' file
grep "cat\|dog" file matches lines containing the word "cat" or the word "dog"
grep "I am a \(cat\|dog\)" matches lines containing the string "I am a cat" or the string "I am a dog"
grep "Fred\(eric\)\? Smith" file   # grep fred or frederic
# grep back references (memory)
grep -i "<H\([1-6]\).*</H\1>" *.html # matches pairs of tags
tel blenkinsop | grep -o "[[:alnum:][:graph:]]*@[[:alnum:][:graph:]]*" # filter just an email address from a text stream (not zsh) *N*

# ls
ls *.h~(fred|foo).h # same thing
ls (x*~x[3-5])   # list files x* except x3 to x5
ls *[^2].php~*template*  # list files with 2nd filter
ls (xx|yy)       # list xx or yy
ls *.(jpg|gif)   # list graphic files
ls fred{joe,sid}.pl
ls fred{09..13}.pl # range
ls fred<76-88>.pl# list all files fred76.pl to fred88.pl range
ls fred<76->.pl  # list all files fred76.pl to fred9999*.pl etc
ls {_,}fred.php  # list files _fred.php fred.php
ls (_|)fred.php  # same effect by globbing
ls *.{jpg,gif}(.N) # do not break if one or other image type absent
# FNG optionally matching a character
ls -l *y{2,}.cfm  #  matches *y.cfm and *y2.cfm *N*
ls -l *y(2|).cfm  #  matches *y.cfm and *y2.cfm *N*
ls *{y2,y}.cfm    #  matches *y.cfm and *y2.cfm *N*
ls *y2#.cfm       #  matches *y.cfm and *y2.cfm *N*
ls foot(fall)#.pl #  match optional string fall
# short version of recursive **/*.php *N*
setopt GLOB_Starshort
ls **.php

setopt no_case_glob  # set ignore case for ls etc
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'   # case insensitive completion for cd etc *N*

# globbing modifiers
# :e just the suffix  (Extension)
# :r removes the suffix  (Remove)
# :t takes away the path (Tail)
# :h takes away one level (Head)
# :a adds full Path (Add)
# . means must be regular files not directories etc
# *(om[1]) picks most recently modified file
# (.N) no warning message if any file absent
ls (#i)*.pmm     # case insensitive globbing (note exact syntax)
ls *(.[2])       # second file in list *N*
ls *(om[1])      # print the most recent file
cp *(om[1])<TAB> # will complete file name
ls *(.om[1])     # print the most recent file (not directory)
ls -l *(Om[1])   # oldest file
mv  *(.om[2,$]) old/   # move all but newest file *N*
ls -lt **/*.txt(D.om[1,5]) # list 5 most recent files in hierarchy
# list 5 most recent files in each sub-directory
dirs=( '' **/*(DM/) ) eval 'ls ${^dirs}*(ND.om[1,5])'
ls {^dev*,}/index.php(.N) # ignore directories beginning dev*
ls (dev*|fred*|joe*)/index* # does not break if no matches
ls **/index.php~dev*(/*)##   # ignore subdirectories dev* multi-level
vi *(.om[1]^D)   # vi newest file ^D means switch off GLOB_DOTS ie ignore dot files
ls *.txt(.om[1]) # ls newest *.txt file  *N*
ls -tld **/*(m-2)# list files modified in last 2 days in hierarchy
ls *(.om[1,5])    # print the 5 most recent files
ls *(.Om[1,5])    # print the 5 oldest files
ls -l *(m4)      # list files modified exactly 4 days ago
ls -ltd *(mw3)   # list files 3 weeks old
ls -1ld *([1,10])# list just 10 files one per line , no directories
ls *(m-1)        # files modified today
ls *(m0)         # files modified today
ls *(^m0)        # files NOT modified today *N*
vi *(m0)         # re-edit all files changed today!
cp *.mp3(mh-4) /tmp # copy files less than 4 hours old
ls -ltd *(mh0)    # list files modified only in last hour
ls *.{aux,dvi,log,toc} # rm latex temp files  *C*
rm ./*(Om[1,-11])# removes all files but the ten newest ones (delete all but last 10 files in a directory)
mv *.*(^m-1) old/ # move all but today its files to sub-directory archive older files *N*
# exact dates (N)
ls -l *.*(mM4)
autoload -U age
ls -tl *.*(e#age 2014/06/01 now#)
ls -tl *(.e#age 2014/06/01 2014/06/30#)
ls -lt *(.om[0,5]e#age 2017-09-01 2017-10-01#) # 5 newest files in September *N*
mv *(.e#age 2017-10-01:00:00:00 2017-10-08:23:59:59#) /tmp # mv all Sept Files

ls [01]<->201[45]/Daily\ report*.csv(e#age 2014/10/22 now#)

files=(${(f)"$(ls *$**)"}(.N))   # store matching files *N*

ls *(n:t)        # order by name strip directory
ls **/*(On:t)    # recursive reverse order by name, strip directory
ls PHP*/**/*.php # recursive but only for subdirectories PHP*
ls *.c(:r)       # strip suffix
ls **/*(.)       # only files no directories (.) means files only
ls -ld *(/)      # list only directories

#oddities
chmod g+w **/*  # group write
[[ FOO = (#i)foo ]]  # case insensitive matching
fred=$((6**2 + 6))      # can do maths
: > /apache/access.log  # truncate a log file

# arrays
X=(x1 x2)               # create an array
print -C 1 $X           # print each array element on it is own line
# 2 dimensional arrays- lookup conversion *N*
typeset -A convtable
convtable=(151 2 152 2 153 2 158 4 159 3 160 2 171 4 172 1 173 4)
echo $convtable[158]
print ${#path}          # length of "path" array
print ${#path[1]}       # length of first element in path array
print ${$( date )[2,4]} # Print words two to four of output of ’date’:
array=(~/.zshenv ~/.zshrc ~/.zlogout)
filelst[$(($#filelst+1))]=$x # append (push) to an array
filelst+=($x)           # append (push) to an array (better)
files=(${(f)"$(egrepcmd1l)"} ) # push a sentence to an array (where egrepcmd1l is a global alias
% print ${array:t}
.zshenv .zshrc .zlogout
# Substring extraction ${parameter:start:length} , default length is rest *N*
a=12345
echo ${a:2:2}
34
echo ${a:2}
345
echo ${a[1,3]}
123

# display shell variables typeset
typeset | grep '^[A-Z]='

# zsh one liners
alias -g NF='*(.om[1])' # newest file
# parse xml file putting each tag on a new line
perl -ne 's/(<\/\w+>)/$1\n/g; print' < NF > $(print NF).txt
cat NF > $(print NF).txt

# variable substitution
somevar="bu&^*ck"                  # variable with mucky characters
print ${somevar//[^[:alnum:]]/_}   # replace all non-alphanumerics with _ the // indicates global substitution *C*
echo ${file##*/}                   # echo just the file name (strip the path)
echo ${texfilepath%/*.*}           # echo just the path (strip the file name)
echo ${file%.*}                    # strip file extension
echo $file:r                       # strip file extension
echo ${0##*[!0-9]}                 # strip all but trailing digit from filename $0
echo ${(M)0%%<->}                  # strip all but trailing digit from filename
file=${1/\//C:\/}                  # substitute / with c:/ ANYWHERE in string
file=${1/#\//C:\/}                 # substitute / with c:/ Beginning of string
file=${1/%\//C:\/}                 # substitute / with c:/ End of string
                                   # note # & % are using to match beginning and end
JUNK=R.E.M.                        # substitute last . for a _
print ${JUNK/.(#e)/_}              # substitute last . for a _
print ${JUNK/%./_}                 # substitute last . for a _
wpath=${wpath//\//\\\\}            # substitute Unix / with dos \ slashes *N*
upath=${wpath//\\/\/}              # convert backslashes to forward slashes (Dos to Unix
dpath=${upath/#\/c\//c:/}          # convert /c/path/ to c:\path\ *N*
foo=$'bar\n\nbaz\n'
print ${foo//$'\n'}                # strip out any carriage returns (some systems use \r) *N*
print ${foo%%$'\n'}                # strip out a trailing carriage return *N*

url='www.some.com/some_strIng-HERe'
anchortext=${${(C)url//[_-]/ }:t}  # titlecase *N*
echo "<a href='$url'>$anchortext</a>"

# creating a family of functions
# generate hrefs from url
function href{,s}
    {
        # href creates an HTML hyperlink from a URL
        # hrefs creates an HTML hyperlink from a URL with modified anchor text
    PROGNAME=`basename $0`
    url=`cat /dev/clipboard`
        if [ "$PROGNAME" = "href" ] ; then
            href="<a href='$url'>$url"
        elif [ "$PROGNAME" = "hrefs" ] ; then
            anchortext=${${(C)url//[_-]/ }:t}
            href="<a href='$url'>$anchortext"
          fi
            echo -n $col
            echo $href > /dev/clipboard | more
    }

# access vim scratch files v1,v2 to v9
function vx{0..9} {gvim.exe c:/aax/${0/#v/} &}

# create vim scratch files va,vb to vz
function vx{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,q,r,s,t,u,v,w,x,y,z}
    {
        scratchfile=${0/#v/}
        gvim.exe c:/aax/$scratchfile &
    }

# regular expressions in zsh  examples *N*
#pcre perl regular expressions   *N*

zmodload zsh/pcre
setopt REMATCH_PCRE

var=ddddd; [[ "$var" =~ ^d+$ ]] && echo matched || echo did not match
[[ 'cell=456' =~ '(cell)=(\d+)' ]] && echo  $match[1,2] $MATCH *N*

var=dddee; regexp="^e+$"; [[ "$var" =~ $regexp ]] && echo $regexp matched $var || echo $regexp did not match $var

# decisions
# cd to different drive depending on Windows login name
drive=$([[ "$LOGNAME" != davidr ]] && echo '/o' || echo '/c') # trad way
cd ${drive}/inetpub/wwwdev/www.some.co.uk/
drive=${${${LOGNAME:#davidr}:+/o}:-/c}                        # zsh way
cd ${drive}/inetpub/wwwdev/www.some.co.uk/

# chaining two modifications
# .om[1] gives newest file
# cyg is a zsh function doing a path conversion e.g. /c/ to C:/ *C*
cyg(){reply=("$(cygpath -m $REPLY)")}
gvim.exe $(echo /c/aax/*(.om[1]))(+cyg) &  ### nested
gvim.exe /c/aax/*(.om[1]+cyg) &            #### both operations

# odd stuff not necessarily zsh
cp -a file1 file   # -a transfer  permissions etc of file1 to file2preserve
# only copy if destination file exists and is older that source file
[[ -e $L/config.php ]] && cp -p -update $T/config.php $L *N*
# variable with variable name
eval "$1=$PWD"

# brilliant will change your life
setopt autopushd                # *C*
dirs -v                         # *N*
cd ~5                           # cd to fifth directory in directory stack
cd -<tab complete> then type number of directory needs compinit *C*
dirs -p                         # display recent directories *N*
cp file ~1                      # where 1 is first entry in pushd stack
#
cp file.txt ~+<TAB>          # select recent directory *N*
ls -1 ~1/*(.om[1])              # newest file previous directory *N*
ls -l  ~-/*(.m0)                # alternative previous directory ~- *N*
pushd +2                        # cd to 3rd entry in pushd stack
#zsh completion
startfilename<tab>           # will complete matching files anywhere in $PATH
startfilename<C-D>           # will list matching files anywhere in $PATH
vi main*~*temp*<tab>         # avoid file with temp in the name
cd /u/lo/li<tab>  completes to /usr/local/lib
#directory sizes
du -sk *(/)
# Inline aliases, zsh -g aliases can be anywhere in command line
alias -g G='| grep -'
alias -g L='| less'
#this reduces a command like
ls | grep foo | less
#to
ls G foo L
#
alias -g R=' > /c/aaa/tee.txt '           # redirect
alias -g T=' | tee /c/aaa/tee.txt '       # tee
alias -g F=' | fmt -'                     # format
alias -g W=' | wc -l'                     # wc
#

# cd by .. or ... or ... or mv file ..../.
alias '..'='cd ..'
alias -g ...='../..'
alias -g ....='../../..'
alias -g .....='../../../..'

# suffix based alias
alias -s jpg='/c/program\ files/IrfanView/i_view32.exe'
now just type the image name to launch irfanview
alias -s php='c:/wamp/php/php.exe'  # now just type test.php to execute it *N*
# named directories (quick jump to a deep sub-directory)
hash -d zsh="/usr/src/zsh"          # create shortcuts to deep directories  *N*
cd ~zsh

#magic equals
vim =some_file                            # edits file anywhere in $PATH
ls =some_file                             # lists file anywhere in $PATH
#magic ** (recursion)
vim **/some_file                          # edits file under under current dir
rm /c/intranet/**/*.stackdump             # specify recursion at a sub-directory *N*
# modifying more than one file (multios)
# writes ls results to file1 & file2 appends to file3
ls > file1 > file2 >> file3 | wc          # multi-io
myscript >&1 >output.txt                  # log a script output
#Redirection to file as well as send on to pipe:
make install > /tmp/logfile | grep -i error

# permissions & ownership *N*
ls *(.f644)                            # files with permissions 644
ls *(.g:root:)                            # files belonging to group root
ls *(.u:apache:)                            # files belonging to user apache
ls -l *(.rwg:nobody:u:root:)              # user has read/write permissions

function g{0..9} { gmark $0 $* }          # declaring multiple functions

# zmv "programmable rename"
autoload -U zmv
# Replace spaces in filenames with a underline
zmv '* *' '$f:gs/ /_'
zmv '(* *)' '${1// /}'
zmv -Q "(**/)(* *)(D)" "\$1\${2// /_}"
# Change the suffix from *.sh to *.pl
zmv -W '*.sh' '*.pl'
# lowercase/uppercase all files/directories (-i) interactive
$ zmv -i '(*)' '${(L)1}' # lowercase
$ zmv -i '(*)' '${(U)1}' # uppercase
$ zmv '([a-z])(*).txt' '${(C)1}$2.txt' ; rename fred.txt to Fred.txt

# initialize zsh/config *N*
autoload -U compinit
compinit
# case insensitive completion
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
     'r:|[._-]=* r:|=*' 'l:|=* r:|=*'

#Wonderful zftp (write ftp scripts as though shell)

# init (could be in .zshenv etc)
autoload -U zfinit
zfinit
zfparams www.someweb.co.uk myuserid mypassword
zfopen
zfcd tips
zfls -l zshtips.html
zfput zshtips.html
zfls -l zshtips.html

# replace every occurence of a file (zsh and bash)
for f in */include/dbcommon.php; do;cp dbcommon.php $f; done
# alternative for loop
# replace every instance of file with new version
for f (**/x) cp newx $f
for f (**/x) {cp newx $f }
for f in **/x; do;cp newx $f; done
# create a clone of a file, modifying it on the fly *N*
for i in {3,4}; sed s/flag=2/flag=$i/ fred.txt > fred$i.txt
for i in {1..9}; sed s/flag=2/flag=$i/ fred.txt > fred$i.txt
# can be simplified to *N*
for f (*.txt) { echo $f }
for f (*.txt) echo $f   # if no ;
for f (*(.)) mv $f fixed_$f
for f (*.csv.csv) {mv $f ${f:r}} # remove one level of extension *N*
for x ( 1 2 {7..4} a b c {p..n} *.php) {echo $x} *N*
# loop a command *N*
while true; do echo "infinite loop"; sleep 5; done
while (true){echo .;sleep 1}
repeat 3 time sleep 3   # single command
repeat 5 ;do date; sleep 5; done # multi
while true ;do date; sleep 5; done # forever
# loop a command *N*
for count in {1..10}; do
r\m x*([1,10]); # delete 10 files at a time
echo "loop $count"
done
for c ({1..50}) {php ./test.php; sleep 5;} *N*

# using vared editor
vared -p "choose 1-3 : " -c ans
case $ans in
 1|a) sdba $key;;
 2|f) sdbf $key;;
 3|i) sdbi $key;;
 *) echo "wrong answer $ans\n" ;;
esac

# the powerful select
PROMPT3="Choose File : "
select f in $(ls **/*.tex |egrep -i "${param}[^/]*.tex")
do
 if [[ "$REPLY" = q ]]
 then
    break
 elif [[ -n "$f" ]]; then
    gvim $f
 fi
done

# multiple script commands on same line
if [ $# -gt 0 ];then string=$*;else;string=$(getclip);fi
if grep -iq 'matching' *.php ;then echo "Found" ;else echo "Not Found"; fi   *N*

# Command on multilines with a backslash
ls \
> x*

# Command on multilines with a quote
sed '
 s/mvoe/move/g
 s/thier/their/g' myfile

# editing a variable (You must try this)
vared PATH

bindkey -v # vi mode line editting
bindkey -M viins '^O' copy-prev-shell-word
bindkey '^L' push-line # push current command into a buffer, allows you to do another command then returns to previous command
# use cat > /dev/null and them press key to get keycode
# configure F7 to output a command
bindkey -s '^v<F7>' "ls -l\n" # configure F7 to output 'ls -l'
bindkey -s "^[[18~" "ls -l\n" # You must actually type Control-v F7 at CLI this is what it looks like on my system :
# put a command string onto f4
bindkey -s "^[OS"  "\^d\^c\n"
# bind control-n to scroll most recent file [*N]
zstyle ':completion:most-recent-file:*' match-original both
zstyle ':completion:most-recent-file:*' file-sort modification
zstyle ':completion:most-recent-file:*' file-patterns '*(.)'
zstyle ':completion:most-recent-file:*' hidden all
zstyle ':completion:most-recent-file:*' completer _files
zle -C most-recent-file menu-complete _generic
bindkey "^N"      most-recent-file

zstyle ':completion:expand-args-of::::' completer expand-args-of
bindkey '^x^a' expand-args-of

# Prompt at end of command line
RPROMPT="[%t]" (display the time)
# colo(u)red prompt
fg_light_red=$'%{\e[1;31m%}'
PS3="$fg_light_red Select file : "
# print fred in blue color
print '\e[1;34m fred'
# color module
autoload colors ; colors
print "$bg[cyan]$fg[blue]Welcome to man zsh-lovers" >> $TTY
PROMPT="%{$bg[cyan]%}%{$fg[red]%}%n%{$reset_color%}%{$bg[cyan]%}@%{$fg[red]%}%m %{$fg[yellow]%}%~ %{$reset_color%}%{$bg[cyan]%}%% "
echo "$bg[blue]$fg[yellow]highlight a message"

curl -u userid:password -d status=" updating twitter with from curl " http://twitter.com/statuses/update.xml

# my .zshenv *N*
autoload -U compinit
compinit
autoload      edit-command-line
zle -N        edit-command-line
bindkey '\ee' edit-command-line
VISUAL='/bin/vim'
EDITOR='/bin/vim'

#textify a phrase to create an image name
s="Fred Goat Dog"
print ${(L)s:gs/ /-/}.jpg
or
print ${(L)s// /-}.jpg

and to de-textify an image

foo=fred-goat-dog.jpg
echo ${(C)foo:gs/-/ /:r}
or
print ${${(Cs:-:):-fred-goat-dog.jpg}%.*}

#new
# read a file into a variable
var="$(<file)"

# Zsh Syntax Aide-Memoire (concentrated)   *N*
cd -<TAB>         # list recent dirs
cp 1.php ~-<TAB>  # list recent dirs
vi *(om[1])<TAB>  # edit newest file
ls *(.mh3)  # modified 3 hours ago
ls *(.mh-3) # less than 3 hours
ls *(.mh+3) # more than 3 hours
gvim -p *(m0)     # all files modified today
mv *.*(^m-1) old/ # move all but todays files to sub-directory
vi -p *(.om[1,3]) # open 3 newest files in tabs (gvim)
ls *(^m0)         # files NOT modified today
ls -l *(m4)       # list files modified exactly 4 days ago
ls *.(jpg|gif|png)(.) # do not break if one or other image type absent
ls ~1/*(.om[1])   # list newest file from previous directory needs setopt autopushcd
ls -lt  **/*~pdf/*(.m0om[1,10]) # up to 10 files modified in last 24 hrs  *N*
rm **/.*.sw?~libs/*(.D) # delete vim swop files *N*
for f (*.php) { diff $f  ${PWD/html/staging}/$f} # diff all files in parallel directories
mv !?main<TAB> # recall previous command containing the string main
vi !?main?$<tab> # recall just last parameter of command containing the string main *C*
scp -rp *(om[1]) [email protected]:$PWD *N*
scp -rp *(om[1]) [email protected]:${PWD/test/live}  *N* modify pwd remote path
rsync -avz --update --existing *(.m0) backup/      # will only copy file if newer than target, no copy occurs if target absent
# upload todays files if newer and existing
rsync -vz --stats  --existing --update *(.m0)  [email protected]:$PWD *N*
ls (x*~x[3-5])    # list files x* except x3 to x5
ls **/*~*/.git/*  # ignore all git subdirectories *~* matches a path
ls (^(backup*|cache*|list*|tmp)/)##*(.) # ignore 4 directories
!!:gs/fred/joe/       # edit previous command replace all fred by joe
cp NF ${PWD/html/release}    # *N*
while (true){echo -n .;sleep 1} # *N* *C*
#super commands
zargs **/*.(js|php|css)~(djr|libs|dompdf)/*~*/junk/* -- grep -i
alias phpall='for f (*.php~test.php(om)) {php -l $f} | more'
alias phpsub=' for f (./(async|inc)/*.php~test.php(om) *.php(om)) {php -l $f} | more' # *N*
alias diffall='for f (*.php~test.php(.om)){diff -q $f ${PWD/html/staging}/$f} 2>&1 | grep differ'
alias -g STAG=' ${PWD/html/staging}'
# End Zsh Syntax Aide-Memoire (concentrated)

mv Licence\ to\ Print\ Money.pdf !#^:gs/\\ //

A=(1 2 5 6 7 9) # pre-populate an array    # *N*
for ((i=1;$#A[i];i++)) echo $A[$i]    # *N*
# debug echo shell commands and provide trace info *N*
# you do need XTRACE if you want to echo whats happening in your script
setopt XTRACE VERBOSE
unsetopt XTRACE VERBOSE

# misc *N*
# switch two previously typed words with alt-t *N*
bindkey "^[t" transpose-words
setopt interactivecomments  # allows end of command line comments
take(){[ $# -eq 1 ]  && mkdir "$1" && cd "$1"} # create a directory and move to it in one go
zmodload -F zsh/stat b:zstat
zstat -g canal-bridge.mov # full files details *N*
# remember current directory : double quotes vital
alias markcd="cd $(pwd)"      *N*
# where is an alias set?
zsh -lxic : 2> >(grep "> alias 'web")

# run a remote zsh script via ssh *N*
ssh 192.168.1.218 -l root "zsh -c 'for i (/usr/*(/)) {ls \$i }'"
# compare local & remote file size *N*
FILE=$(echo *(.om[1])) && ls -l $FILE && ssh 192.168.1.1 -l root "zsh -c 'ls -l $PWD/$FILE'"
# remote login in with zsh
ssh -t [email protected] 'sh -c "cd /tmp && exec zsh -l"'
# launch zsh not as sub-shell *N*
exec zsh
# which shell active *N*
ps -p $$ | grep $$ | awk '{print $NF}'
# zsh menu
echo "enter 0-2,a"
read ans ; # read in a parameter
case "$ans" in
 0|${prog}0) cd "$(cat /c/aam/${prog}0)" ;;
 1|${prog}1) cd "$(cat /c/aam/${prog}1)" ;;
 2|${prog}9) cd "$(cat /c/aam/${prog}9)" ;;
 a|${prog}l) cd "$(cat /c/aam/${prog}a)" ;;
 **) echo "wrong number $ans\n" ;;
esac

# zsh hook functions #N#
chpwd,periodic,precmd,preexec , zshexit, zshaddhistory
preexec(){ echo using $@[1]}

# useful aliases
# swap / flip between 2 deep parallel directories *N*
alias flip=' cd html live > /dev/null &>1 || cd live html > /dev/null &>1'
# syntax-check all php files in date order excluding certain
alias phpall='for f (*.php~test.php(om)) {php -l $f}'
# diff all files in parallel directories in date oder (exclude certain)
alias diffall='for f (*.php~test.php(.om)) { diff -q $f  ${PWD/html/staging}/$f}'

# locating/identifying stuff *N*
which zsh
whence -vsa ${(k)commands[(I)zsh*]}  # search for zsh*
locate zsh
cd $(locate -l1 -r "/zoo.txt$")(:h) # cd to directory of first occurence of a file zoo.txt (N)
cd ${$(locate zoo.txt)[1]:h}   *N*
cd **/resource.php(:h) *N*

str=aa,bb,cc;print ${(j:,:)${(qq)${(s:,:)str}}} # quotify a string *N*

# completion
# define tab-completable parameters p1,p2,p3 for your widget
compdef "_values 'widget tool' p1 p2 p3" widget
widget
p1 p2 p3

# bind history to up down keys
autoload -U up-line-or-beginning-search
autoload -U down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey "^[[A" up-line-or-beginning-search
bindkey "^[[B" down-line-or-beginning-search

# insecure directories warning on cygwin
# #run compaudit
# compaudit
# #It told me that my latest zsh install was insecure (directories were writable)
# # The following solved the problem
# chmod -R 755 /usr/share/zsh/
# chown -R myusername /usr/share/zsh (on Vista (as admin)

# start zsh from a windows short cut
C:\cygwin\bin\mintty.exe -i /Cygwin-Terminal.ico /bin/zsh --login

Sources newsgroup gmane.comp.shells.zsh.user newsserver news.gmane.org

:!zshtipsftp
# Upload this page 

##########################################

# Zsh Daily Tips on Twitter Archive
#---------------------------------#

Zsh Daily Tips on Twitter Archive

# Clean up file names and remove special characters
# $1 holds path $2 filename
zmv -n '(**/)(*)' '$1${2//[^A-Za-z0-9._]/_}

zmv '(*)' '${(L)1}'  # lowercase file names
zmv 'pic(*).jpg' 'pic${(l:4::0:)1}.jpg' #  pic1.jpg,pic11.jpg to pic0001.jpg,pic0011.jpg (pad 0)

# zmv regexp memory renaming
autoload -U zmv
zmv '(*).html' '$1.php'
zmv '(*)_(*)' '$1-$2'

# awkward file names trick
touch ./-Mike.txt
rm -Mike.txt
rm: unknown option -- M
Try 'rm ./-Mike.txt' to remove the file �Mike.txt�

# estring take control of what is listed
print -rl **/*.A(.e_'REPLY=$REPLY:r; [[ -f $REPLY.B ]] ; echo $REPLY.{A,B} '_) > /dev/null

# splitting PATH variable
for e in ${=PATH//:/ };echo $e
for e in ${(s(:))PATH};echo $e
for e in $path[@];echo $e
for e ($path[@]){echo $e}

# files not matching 'pattern'
print -rl -- *(.^e{'grep -q pattern $REPLY'})
or
: *(.e{'grep -q pattern $REPLY || print -r -- $REPLY'})

# count with estring
ls **/*(e:'[[ -e $REPLY/index.php && -e $REPLY/index.html ]]':)
ls **/*(e:'l=($REPLY/index.*(N)); (( $#l >= 2 )) ':)

# estring
# find c files with more than 10 lines
ls **/*.c(-.e{'((`wc -l < $REPLY` > 10))'})

# estring qualifer
print **/*.c(e_'[[ -e $REPLY ]]'_)  # neutral just lists
# c files w/o  .o
print **/*.c(e_'[[ ! -e $REPLY:r.o ]]'_)

alias -g NL1=' ~1/*~vssver.scc(om[1])' # newest file in previous directory
alias -g NL2=' ~1/*~vssver.scc(om[2])'
cp NL2 .

# detect if variable exists null value or not
echo ${+PS1} ${+xyq}
1 0
xyq=''
echo ${+PS1} ${+xyq}
1 1
man zshexpn

# $match
sstring="before inside after"
[[ "$sstring" = (#b)([^i]#inside)(*) ]]
echo $match[1]
echo $match[2]

# match word beginning
[[ "foo bar" = *([^[:WORD:]]|(#s))bar* ]] && print yes
[[ "obar foo" = *([^[:WORD:]]|(#s))bar* ]] || print no

# zed simple editor
autoload zed
zed myfile.txt
zed -f myfunc
https://t.co/qUlSHL6Uzl

# previous directories
setopt autopushd
autoload -U compinit && compinit
echo  ~- ~1 ~2 ~-1 ~-0 ~0
cd -<tab>
cp ~-<tab><tab> ~2<tab>

# precise dates/times
autoload -U age
ls -tl *.*(e#age 2015/06/01 now#)
ls -tl *(.e#age 2015/06/01 2015/06/30#)

# latest zsh 5.1
http://t.co/fL349fSlty

# navigate aliases, functions, history etc
https://t.co/wpKFMx1Ap8

# oh-my-zsh has 'take' (create subdir and cd to it, here is my attempt
take(){ [ "$#" -eq 1 ] && mkdir "$1" && chdir "$1"}

# edit command in vi: Esc-v or ALT-V bring up $EDITOR
EDITOR='/bin/vi'
autoload  edit-command-line
bindkey -M vicmd v edit-command-line

print *(e*'reply=( this ${REPLY}* )'*)
What problem is this solving?
find out at http://t.co/L7YW0oLDsl

# clean up file name : generic substitute
setopt extendedglob
file='a b__c_  d.gif'
print ${file//[_ ]##/-}
a-b-c-d.gif # result

# grep2awk
# https://t.co/MyW1x9sxli
# grep2awk is a zle function turns the first grep in the current command line into its awk equivalent,cursor unchanged

# vi cli edit
bindkey -v 
# eliminate double click of ESC problem where first key stroke ignored
# bind esc to nothing
bindkey -as '\e' ''

# remote login in with zsh
ssh  -t [email protected] 'sh -c "cd /tmp && exec zsh -l"'

# you need 5.0.8
ps gvim<tab>
# lists just the jobs gvim

setopt autopushd
cd -<tab>
alias 1='cd -1'
alias 2='cd -2'
alias 3='cd -3'
alias 4='cd -4'

touch {a,a1}.php
ls a1#.php
a.php  a1.php
ls a1##.php
a1.php
X# Zero or more  X
X## One or more  X

ls *.php<Ctrl-C>
echo $ZLE_LINE_ABORTED
ls *.php

# list files that are different on remote server
rsync -rvnc --exclude '*.scc' [email protected]:${PWD/staging/release}/ .
#  n dryruN

useful global aliases
alias -g ...='../..'
alias -g ....='../../..'
alias -g .....='../../../..'
cp 1.php ....
cp ...<TAB>

REPORTTIME=5
will automatically report time for any command which lasts longer than 5 secs
info --index-search="reporttime" zsh

# chpwd is run every time you cd (chdir) use it to change console title etc
where chpwd  # to see what if anything is in yours

#  hooks (b4 every command precmd if it exists)
> precmd(){echo 'anything you want'}
> date
Thu, Jun 04, 2015  8:13:38 PM
anything you want

# movable
scp -rp *(om[1]) [email protected]:$PWD
# movable & modify path
scp -rp *(om[1]) [email protected]:${PWD/test/live}

# upload todays files
scp -p *.php(m0) [email protected]:/var/www/html/report/

# get latest file  including possible dot files (D)
ls *~vssver.scc(.om[1]D)

# my first stab at an aide-memoire of the bits of zsh I use frequently
http://t.co/wZOFoBeq9t

# exclude directory at any depth e.g. junk
 ls **/fred.jpg~(|*/)junk(|/*)
# e.g. exclude /*junk*/
ls **/fred.jpg~(|*/)*junk*(|/*)

# you can chain file globs
ls -1 ./(async|inc)/*.php~test.php(om) *.php(om)
for f (./(async|inc)/*.php~test.php(om) *.php(om)) {php -l $f}

# use variable function name to share script but change behaviour
fun{a,b}(){echo $0}  # create funa funb

fun{0..9}(){echo $0} # fun0-fun9

# zsh show ambiguity, useful when completing on files with very similar names

http://t.co/VFCMeAHlN7

info --index-search="ambiguity" zsh

# retrieving a particular parameter from history
ls xx vv hh bucket fred
...
...
vi !?buck?^  # first
echo !?fred?2  # 2nd

# select 3rd file
ls  xyz*
vi !$([3])

info --index-search="zcalc" zsh
autoload zcalc
zcalc '23.0 / 3'
zcalc
PI*2

Collection of ZSH frameworks, plugins, tutorials & themes
https://t.co/0wgaqnaMoK

file + full path
echo ost-config.php(:a)
/var/www/osticket/upload/include/ost-config.php
# did not explain this tip properly (:a) (all)

exclude extensions and exclude directories
ls -1t  report/**/^(vssver.scc|*.js|*.png|*.bak)~*/(async|images)/*(.om[1,20])

accessing output of locate (assumes no spaces in file names)
a=($(locate my.cnf))
cd ${a[1]}(:h)
vi ${a[1]}

see your directory tree
ls -d /var/www/html/**/*(/)

pathtovim==gvim
echo $pathtovim
/cygdrive/c/VIM/VIM74/gvim

# DIY zsh write your own functions
# ignore .scc .bak .obj
not(){reply=("$(echo $REPLY |grep -iva '.scc\|.bak\|.obj')")}
ls fred.*(+not)

# global sed substitute
zargs **/*.(php|inc) -- sed -i 's#ereg_replace("\([^"]*\)"#preg_replace("/\1/"#g'
# preg_replace requires //

# of course you could also do to get the first match
cd **/note027.txt([1]:h)
# zsh is a bit like lego just bolt another bit on

# cd to directory containing report.php
cd **/report.php(:h)
# fails if more than 1 report.php

# access time picks up files that have been "used" ie cat,edit etc
ls -l *(.aM-1)
 the date shown will be confusing so use
 ls -lu *(.aM-1)

ls -l *(mh-2)  # modified in past 2 hrs
ls -l *(ch-2)   # changed in past 2 hrs, also picks up files that have been moved/renamed

# filter by permissions read-write-execute 4-2-1
ls y*(.f777)
ls *.jpg(f644)

# line continuation
[ -e file1 ] && [ -e file2 ] && echo 'both'
# or
[ -e file1 ] &&
[ -e file2 ] &&
echo 'both exist'
# or
ls ;\
date

zmodload -i zsh/mathfunc
echo $(( pi = 4.0 * atan(1.0) ))
print $(( rand48(seed) ))
echo $(( sin(1/4.0)**2 + cos(1/4.0)**2 - 1 ))

# filter by ext,exclude dirs,filter by size,date,owner,group,perms
ls -l **/*.(js|php|inc)~(junk|libs)/*(.Lk-2m-14u:nobody:g:apache:xXom[1,3])

# from http://t.co/lgepDuH7mr
ls -l **/*(.Lm-2mh-1om[1,3])
Lm-2 # <2mbs
mh-1 # less 1 hr
om[1,3] most recent 3

# list files newer than 22/10/14 from specific directories
autoload -U age
ls [01]<->201[45]/Daily\ report*.csv(e#age 2014/10/22 now#)

# ls allfiles except dotfiles filesonly
# ls positive glob ~ negative glob (modifiers) e.g. list all files without an extension ( no dot)
ls *~*.*(.)

# man zshall
# better search the zsh man pages
# e.g.  for bindkey
info --index-search=bindkey zsh
zinfo(){info --index-search="$*" zsh}

# backup a file with a prefix
cp longfilename.php backup_!#^
cp {,backup_}longfilename.php   # pretty cute

# backup a file (with a suffix)
cp longfilename.php !#^:r.bak
cp longfilename.{php,bak}   # alternative

cp longfilename.php !#^:r.bak
or
cp longfilename.php !#$:r.bak
or
cp longfilename.php !#$:s/php/bak/
# use <tab> to complete, more tomorrow

# Current line history
!#:0    command
!#^     first
!#1    first
!#1-4  first 4
!#$     last
!#*     all
!#-    all but last

# The D operator allows you to include dot files in a glob. D is for DOT FILES
ls *(.D)  # include dotfiles
touch .xxx xxx
ls *xxx*(.)
xxx
ls *xxx*(.D)
.xxx xxx

# precise date filtering
autoload -U age
ls -lt *(.e#age 2014/10/15 2015/01/15#)

# archiving old files
mv  *(.mM+12) old/     # files older 12 mths
mv *(/mM+12) 2013archive/ # old directories

m[Mwhms][-+]n
*(.mh3)  # 3 hrs ago
*(.mh-3) # < 3 hrs
*(.mh+3) # > 3 hrs
*(.^m0) # not today
*(.mw0)  # this week
*(.mM1)  # last month

# :a modifier display full path
ls *(.:a)

:e :h :t :r  modifiers
 $f:e is $f file extension
   :h --> head (dirname)
   :t --> tail (basename)
   :r --> rest (extension removed)

# newest file from previous directory
setopt autopushcd
vi ~1/*(.om[1])

# ZSH-Lovers  List files in reverse order sorted by name
print -rl -- *(On)
 # or
print -rl -- *(^on)

# Remove zero length and .bak files in a directory
rm -i *(.L0) *.bak(.)

# All files in /var/ that are not owned by root
ls -ld /var/*(^u:root)

# I will now start randomly tweeting gems from http://t.co/imT2cMf0wx

echo $[${RANDOM}%1000]

# mastering $REPLY
# list .c files with no .o
touch {f,j}.{c,o} k.c l.c
print *.c(e_'[[ ! -e $REPLY:r.o ]]'_)
# _ delimits :r strip .c

# DIYcompletion widgets
# gvim needs DOS path so does not work
gvim ~/.zshrc 
gvim ~/.zshrc(+cyg)
cyg(){reply=("$(cygpath -m $REPLY)")

# online zsh help
http://t.co/1I706qiJhH
http://t.co/e1zvJKuCUO
http://t.co/736NmOcFe0

# what's in his dot files

http://t.co/5qwgkTO1RI

# remember you have completion on man
man zsh<tab>
zsh zshall zshbuiltins  zshcompctl   zshcompwid   zshexpn   zshmodules etc

# Productivity Tip 14
modifying previous command
r oldstr=newstr
^fred^joe
^str1^str2^:G
^str1^str2^:u:p
!!:gs/fred/joe/

# Productivity Tip 13
What's been updated?
alias lsnew='ls -lt  **/*(.om[1,10])'
alias lsnew2='ls -lt  **/*(php,inc,js,css)(.om[1,10])'

# Productivity Tip 12
Search a web root with exclusions
alias zg='zargs **/*.(js|php|css|inc)~(libs|test|temp|wiki|dompdf)/* -- grep -i '

# Productivity Tip 11
# diff all files in parallel directory
alias diffall='for f (*.php~test.php(.om)) { diff -q $f  ${PWD/html/staging}/$f}'

# Productivity Tip 10 - syntax check all php files in date order
alias phpall='for f (*.php~test.php(om)) {php -l $f} | more'

# Productivity Tip 9
REL dynamically readjusts to parallel dir
alias -g REL=' ${PWD/html/release}'
diff index.php REL
cd inc
diff main.inc REL

# Productivity Tip 8 - powerful history
# Recall just last parameter from history which contains string sql
ls !?sql?$<tab>

# Productivity Tip 7 - jump to any recently visited directory with cd -<tab>
autoload -U compinit && compinit
setopt autopushd
cd  -<tab>

# Productivity Tip 6 up-line-or-beginning-search or down-line-or-beginning-search
# type php then up/down arrow through history of previous php

# Productivity Tip5 - :globals to create meta-lang
# newest file
alias -g NF='*(.om[1])'  
# newest directory
alias -g ND='*(/om[1])'  
cp NF ND

# ZSH Productivity Tip 4 - the modifiers
# copy todays mp3 only
cp *.mp3(m0) g:/   

# edit newest file
vi *(om[1])            

# zsh Productivity Tip 3
# **/* with +ve & -ve filtering .use an alias
grep -i 'fred' ./(junk|colin)/**/*.(php|inc|js)~(**/wiki|**/dompdf)/*

# ZSH Productivity Tip 2
# By binding _expand_alias to the Tab key I can tab-expand my aliases and modify them as necessary thus fewer aliases

# zsh productivity tip 1 - named roots
hash -d www='/var/www/html'
hash -d del='/tmp/del'
cd ~www/www.site.com
mv file ~del

# elegance of the for loop
for f (*) mv $f $f.sql
# (.) files only
for f (*(.)) mv $f $f.sql

# basic zsh filter
ls -1 file*
# select 3rd file in list
vi file*([3])

# contain keyword
gvim -p $(grep -il 'dunk\|gunk' **/*(.))
gvim -p $(grep -Eil '(dunk|gunk)' **/*(.))
gvim -p $(grep -REil '(dunk|gunk)' .)

# zmodload -F zsh/stat b:zstat
# detailed stats on a file
zstat -g canal-bridge.MOV

# referring to previous tweet
# complete either end
ls joe<tab>
# completes xxxjoeyyy.txt
# equivalent to
ls *joe*<tab>

# autoload -U compinit && compinit -i
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \
    'r:|[._-]=* r:|=*' 'l:|=* r:|=*'

# try expanding grep !!
grep -<TAB>
# there are 164 different options

# expand parameters (help)
autoload -U compinit && compinit -i
chmod +<TAB>
X  -- execute
g  -- group
o  -- other'
r  -- read
.. etc

# servi<TAB>
service htt<TAB>
service httpd res<TAB>
service httpd restart

# expand alias
autoload compinit && compinit
alias e='echo'
zstyle ':completion:*' completer _expand_alias _expand _complete _ignored
e<tab>

# man for all the zsh builtins from alias to ztcp

http://t.co/gNf9dfXeGM

# ls -l *.*(mh-3)   # less than 3 hours
ls -l *(.mh-3)    # . means files only

# test if a parameter is numeric
if [[ $1 == <-> ]] ; then
echo numeric
else
echo non-numeric
fi

# copy-earlier-word bound to say control-o
cycles through  each parameter on command line very useful

# autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey -M viins '^O' copy-earlier-word
cp fred.php old_^O^O #  to old_fred.php

# one spelling variation
touch bungo bango tango
ls (#a1)bungo
bango  bungo
# two spelling variations
ls (#a2)bungo
bango  bungo  tango

# glob by owner, permissions, age, file size
# filenames no digits ,uppercase
ls -l **/([^A-Z[:digit:]])##(.u:Guest:f:gu+wx,o+wx:Lk-30mM-1)

# lets push the boat out a bit further
echo **/*(.Lk-2m-9om[1,9]:t:r:uu:Guest:)

# . files only
Lm-2  Less than 2MB
mh-1 Less than 1 hour old
om sort by newest
[1,3] first 3 only
from http://t.co/lgepDuq4kr

# explanation tomorrow
ls -l zsh_demo/**/*(.Lm-2mh-1om[1,3])

# The fignore variable lists suffixes of files to ignore during completion
#  http://t.co/TgsrhUKmIS
fignore=( .o \~ .bak .junk .scc)

# lets be real picky
autoload -U age
ls -l *(.e#age 2013/10/04:10:15 2013/11/04:10:45#)

# list by age/date
ls -l *.*(mM4)
autoload -U age
ls -tl *.*(e#age 2014/06/01 now#)
ls -tl *.*(e#age 2014/06/01 2014/06/30#)

# zsh tips archive
vim http://t.co/vrjqXYSxES

# expand aliases with tab
autoload -U compinit && compinit
zstyle ':completion:*' completer _expand_alias
bindkey '^t' _expand_alias

# part 3
bindkey "^[[A" up-line-or-beginning-search
bindkey "^[[B" down-line-or-beginning-search
ls <up> only lists previous ls history

# part 2
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search

# part 1 Better history searching with arrow keys
autoload -U up-line-or-beginning-search
autoload -U down-line-or-beginning-search

# list your functions
# o=order k=keys
print -l ${(ok)functions}

# % minimum match %% maximum match
v=fredjoejoe
echo ${v%joe*}
echo ${v%%joe*}

# from today's zsh user group : alter last dot to _
 JUNK=R.E.M.
echo ${JUNK/%./_}
echo ${JUNK/.(#e)/_}
# % & (# e) are end anchors

# cd without typing cd
setopt auto_cd

# parameters
p()
{
echo "last ${@[-1]}"
echo "2nd last ${@[-2]}"
}
p a b c d

# :r remove extension :wr multiple
var=fred.txt
echo ${var:r}
var='fred.txt joe.csv sue.xls'
echo ${var:wr}

# setopt correct
alias grepp='nocorrect grepp'
unsetopt correct
setopt correctall # spellchecks everything
unsetopt correctall

X# Zero or more  X
X## One or more  X
touch {4,44,444,5,45,55,54}.txt .txt
ls 4#.txt
ls 4##.txt

^pat Anything that doesn’t match pat
pat1^pat2 Match pat1 then anything other than pat2
pat1~pat2 Anything matching pat1 but not pat2

# print components of date command
print ${$( date )[2,4]}

# diff ^ ~
touch {fred,joe}{fred,joe}
ls fred*~*fred*  # never matches
ls fred*~*joe*  # finds fredfred
ls fred^fred # finds fredjoe

#   # followed by c repeat characters
 touch DATA_6789{00..33}.csv DATA_678988888.csv
ls DATA_[0-9](#c6).csv
ls DATA_[0-9](#c6,).csv

# repeat command
repeat 3 echo hi

# eliminate the annoying no match warning for FNG
unsetopt nomatch

# you can chain ~ filters
touch {a,b,c}{a,b,c} {0,1,2}{1,2,x}
ls *~*c~*b
ls *~b*~c*~<->    # <-> numbers
 ls *~*c~2#       # filter 22 222

# ^ not in fng
ls x^[3-5]
ls fred^erick*    # list all files fred* except frederick
ls abc^8* ls -lt **/^(vssver.scc|*.ini)(.om[1,10])

# zsh maths from http://t.co/imT2cLGmmt
zmodload zsh/mathfunc
echo $(( pi = 4.0 * atan(1.0) ))

# ~ with number ranges
touch abc{0..100}.txt
ls abc(<20-100>~<57-67>).txt

#  how ~ filters
grep -i 'goaty' **/*.{js,php,css} | grep -v 'libs/\|test/\|tmp/'
grep -i 'goaty' **/*.{js,php,css}~*(libs|test|tmp)/*

# printable zsh reference card
http://t.co/nC7rfzD4Sa

autoload -U url-quote-magic && zle -N self-insert url-quote-magic

#  This will auto-quote/escape URLs when typed or pasted

# games
autoload -U tetris
zle -N tetris
bindkey '^T' tetris

# zsh tips tweets archive
http://t.co/vrjqXYSxES

http://t.co/l4EUN1Bs5s

# allow comments on command line
setopt interactivecomments
date # this comment no longer breaks command

# good stuff
http://t.co/lgepDuq4kr

touch -d "4 days ago" x* a* .x .a
ls *(.m4) # 4 days ago
ls *(.m4om[2]) # 2nd file 4 days ago
ls {x,a}*(.m4om[2]D)  # include dot files

# remember you can dry run a command with echo
# mv all files changed in last hour
echo mv -- *(.ch-1) junk/

touch x y .x .y
ll *(m0)    # all files today but gets sub-directories
ll *(.m0)   # only files today
ll *(.m0D) # include dot files

# separate permissions for files and directories
chmod 755 **/*(/)
chmod 644 **/*(.)

# http://t.co/YCW5X4V0k4
unit specifiers ‘M� �� ‘h� ‘m�or ��(e.g. ‘mh5� months weeks, hours, mins or secs ‘d�for days is default.

ls *.*(mh3)  # modified 3 hours ago
ls *.*(mh-3) # less than 3 hours
ls *.*(mh+3) # more tham 3 hours
ls *.*(^mh3) # not 3 hours

# diffing al files in parallel directories /var/www/html/ var/www/test/
alias diffphp='for f (*.php) { diff $f  ${PWD/html/test}/$f}'

# alternative for loop
# replace every instance of file with new version
for f (**/x) {cp newx $f }
for f in **/x; do;cp newx $f; done

# alternative ways of cd-ing to deep paths
hash -d dd="/var/www/html/scripts/dd/"
cdpath=(~ /var/www/html/)

# a simple completer for latex files
zstyle ':completion:*:*:vtex:*' file-patterns '*.tex:tex-files'
function vtex(){gvim $*}
vtex<TAB>

# multiple redirection
 cat file.txt > file1.txt >> file2.txt > file3.txt

# textify a phrase to create an image name
s="Fred Goat Dog"
print ${(L)s:gs/ /-/}.jpg
print ${(L)s// /-}.jpg

# vi mode multiple undo/redo
bindkey -a u undo
bindkey -a '^R' redo
bindkey '^?' backward-delete-char
bindkey '^H' backward-delete-char

# reply gets each file name
$REPLY:r.o
:r strip extension
.o add .o
[[! -e $REPLY:r.o]]  # does *.o exist
e#''#   execute condition

# find *.c files which have no *.o
touch  {a,b,c,d}.c {a,c}.o
ls *.c(e#'[[ ! -e $REPLY:r.o ]]'#)

# test if a file exists before overwriting
[[ -e test/config.php ]] && cp -p test/config.php www/

for f (*.php) { php -l  $f }
for i in {11..15} ; ping -n 1 192.18.158.$i

# please memorise syntax for recalling an individual param
# !?string?0-$
ls file0PGwerlongname.csv
.. other commands
vi !?file0?$<TAB>

# list  user root files which are not executable
ls -l *.*(u:root:.^x)

# working with file ownership
# list files not owned by user apache
ls -dl *(^u:apache:)

if [[ $1 == <-> ]] ; then
echo parameter is a number
else
echo $1
fi

# edit/correct previous command :G global :u uppercase :p just display & memory
echo fred
^fred^joe
^joe^& &
^joe^sid^:G
^sid^sue^:G:u:p

# what's been modified today?
ls -lt  /var/www/html/**/*(.om[1,10])

# attach a command, text etc to a key, use with care
 bindkey -s qq 'ls **/*.php'
# to get code of a function key type cntl-v f5  ^[[15;5~

# list files younger than 6 hours
ls *.*(mh-6)
# m =modified  h-6 hours - 6
# list files older than 6 hours
ls *.*(mh+6)

# simple but useful
# copy today's files to a USB
cp *(m0) f:/
cp *.mp3(m0) f:/
# where m0 is m zero

# Global
zstyle ':completion:*' completer _expand_alias _expand _complete _ignored
vi NF<TAB>
vi *~vssver.scc(.om[1]) <TAB>
vi news.php

# FNG choices
touch {bb,aa,cc}.{jpg,gif,png}
ls {aa,bb}.(jpg|gif)
ls (*~aa).(*~gif)

# zsh magic : recall recent directories
setopt autopushd pushdignoredups
cd -<TAB>
cp main.php ~-<TAB>

# FNG
touch {y,y2}.cfm
ls y2#.cfm y{2,}.cfm y(2|).cfm {y2,y}.cfm (y|y2).cfm y*.cfm

# renumbering images
autoload zmv
autoload zmv   $ zmv 'pic(*).jpg' 'pic${(l:4::0:)1}.jpg'

# find all files with no extension
ls *~*.*(.)
# * match all files
# ~*.* except any with a dot
# (.) files only

# padding left & right
value=314.56
echo ${(l:10::2:)value}
echo ${(r:10::0:)value}

# num ranges ad nauseum
touch {1..5} {6,7,8,12} {00..03}
ls <-> <-6> <4-> <4-5> 0<-> {1..5} {2,3} {00..03} (4|5) [3-4]  [3-47-8] 0? ?2 *2

# number ranges
touch x{1..5} {9..6}
ls x<0-5>
ls <->

# builtin random number $Random
for i in {1..9}; echo $RANDOM

cd /v/w/h/<tab>
# expands to
cd /var/www/html/

# use global alias to replace complex syntax
alias -g REL=' ${PWD/html/release}'
# you must use single quotes here

# now exclude some directories
zargs ./{html,live}/**/*.{php,inc,js}~(**/wiki|**/dompdf)/* -- tar rvf /tmp/web2$(date "+%d-%m-%Y").tar

# backup two webroots dev and html
zargs ./{html,dev}/**/*.{php,inc,js} -- tar rvf /tmp/web$(date "+%d-%m-%Y").tar

# previous tweet saves a command in history that you are not ready to execute
$BUFFER contains command
print -s means print to history

# ctrl-b save
commit-to-history() {
print -s ${(z)BUFFER}
zle send-break
}
zle -N commit-to-history bindkey "^B" commit-to-history

# type bindkey to see what  is configured
bindkey
# also set, setopt, mount, alias, autoload, functions, zstyle
# use | more as required

zargs ./**/*.{php,inc,js} -- tar rvf /tmp/webbackup$(date "+%d-%m-%Y").tar

# debug echo shell commands and provide trace info
setopt XTRACE VERBOSE

# duality of operators :u :l etc
f=FreD
echo ${f:u}
echo FreD
echo !$:u

# http://t.co/Alky15TAaS
!!:1:s/s1/s2/ Replace string s1 by s2
!!:1:gs/s1/s2/ Same but global
!!:1:& Use same s1 and s2 on new target

ls -l *(Lk+100)   # list file size larger/greater than 100kb
 ls **/*(.Lm+10)   # list files larger than 10MB anywhere in hierarchy

# flip between two deep parallel directories
cd /var/www/html/admin
cd html live > /dev/null &>1 || cd live html > /dev/null &>1

# just fun but memorise these
touch do re mi
!!:0 !^ !:2 !$ !#$ !#:2 !#1 !#:0

# lowercase/uppercase all files/directories
zmv '(*)' '${(L)1}' # lowercase
zmv '(*)' '${(U)1}' # uppercase
# the syntax is logical

# Bulk change the suffix from *.sh to *.pl
zmv -W '*.sh' '*.pl'

# zmv advanced renaming  , replace spaces by underscore
autoload -U zmv
touch 'filename with spaces.txt'
zmv '* *' '$f:gs/ /_'

# number ranges
ls fred{09..13}.pl
# list all files fred76.pl to fred88.pl
 ls fred<76-88>.php

#  cd to deep dirs from anywhere
cdpath=(~ /c/inetpub/wwwroot/  /c/intdoc/)
cd website1
# where website1 is /c/inetpub/wwwroot/website1/

# start zsh without your usual config (for testing etc)
zsh -f

# tip part 2
# with previous tweet
ls fred<tab>
# will complete middle of filename e.g. longfred.txt

# tip part I
autoload -U compinit && compinit
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'   'r:|[._-]=* r:|=*' 'l:|=* r:|=*'

# oh my zsh a project to facilitate configuring zsh
https://t.co/9tUvMIztjt

# elegant ftp
autoload -U zfinit
zfinit
zfparams http://t.co/FV4p7oNuqI userid password
zfopen
zfput zshtips.html

# check syntax of PHP files with quote in name
for i in quote_* ; php -l $i

# recall from current line
cp longfilename.php backup_!#^<TAB>
# here !#^ !#1 !#$ all recall longfilename.php
# also !#0

# expands to mv textfile.txt textfile.bak
mv textfile.{txt,bak}

# create a backup copy of a file
cp {,bak_}verylongfilename.tex

# another way to edit a previous command
!-2:gs/fred/joe/
!?php5?:gs/5/6/

# newest directory
alias -g ND='*(/om[1])'
# newest file
alias -g NF='*~vssver.scc(.om[1])'
cp NF ND

# variety
ls *.{jpg,gif,png}
ls *.{jpg,gif,png}(.N)   # does not break if one type missing
ls *.(jpg|gif|png)

# very good, simply explained
http://t.co/yEFBz3wZu1

ls **/*~*/.git/*
# ignore all git subdirectories *~* matches a path

# copy to a deep parallel directory
cp ${PWD/dev/html}/getRecord.php .
# e.g from /var/www/dev/include/ to /var/www/html/include

# push current command into a buffer, allows you to do another command then returns to previous command
bindkey '^L' push-line

# for previous tweet you need, also you can program any key
bindkey -v # vi mode line editting

bindkey -M viins '^O'   # copy-prev-shell-word

cp longname.php <control-O> duplicates longname.php which you then modify

bindkey '^[[A' history-beginning-search-backward # Up
bindkey '^[[B' history-beginning-search-forward # Down
cd (up recalls prev params)

# writes ls results to file1 & file2 appends to file3 . multi-io
ls > file1 > file2 >> file3 | wc

# recall most recent cmd containing string 'client'
!?client<tab>

# recall last parameter of cmd containing 'client'
vi !?client?:$<tab>

# history substitution
!^      first parameter
!:1-4   first 4 parameters
!$      last parameter
!*      all parameters

# ^^ correct /alter previous command
cp x2 src/
^2^3
cp x3 src/

# list 5 most recent files anywhere in hierarchy
ls -lt **/*(D.om[1,5])

* all files
~ except for
*.* all files with a dot
(.) files only

# list all files without an extension ( no dot)
ls *~*.*(.)

# list pesky empty files (yes that is a zero)
ls *(.L0)

# autocd is where you just have to type the directory name to "cd" to it. Are there any drawbacks to autocd?
# type ... to go back up 2 directory levels
alias ...='cd ../..'

# .zshrc : access vim scratch files vx1 to vx9
function vx{0..9}(){gvim.exe c:/aax/${0/#v/} &}

# create shortcuts to deep directories (put in .zshrc)
hash -d www="/var/www/html"
cd ~www

# now just type test.php to execute it
alias -s php='c:/wamp/php/php.exe'  

yum install zsh  # on many linux systems, for cygwin users select zsh from the setup.

ls (x*~x[3-5])    # list files x* except x3 to x # thank You Steve Mac my first follower!

zargs ./**/*.{php,inc,js} -- tar rvf dev2$(date '+%d-%m-%Y').tar # tar just source files in a directory

cd str1 str2 # this will substitute the string "str1" from your directory path and replace  it with "str2".

ls -lt  **/*.php(.om[1,20]) # list 20 newest php files anywhere in directory hierarchy

ls *(m0)   # list all files modified in last 24 hours

mv *.*(^m-1) archive/ # move all but today its files to sub-directory archive

vi ~+<tab> 1 /c/aaz 2 /c/aaa 3 /c/aax 4 /usr/bin  # vi a file in recently visited directory

cd ~<tab>  # display a list of recently visited directories then select the one you wish to return to

vi **/myfile.txt   edit a file somewhere in hierarchy

# The elegant way zsh handles recursion. list all files main.php, main.css anywhere in directory / subdirectories >
ls -l **/main.{php,css}

# Right now I am logged into a server with a massive 4 petabyte filesystem within the Scholarly Data Archive at @iu_pti. I think the whole service has 42PB total storage. Someday this tweet may not be impressive, but not today! :D
# When brace expansion just will not cut it. Requires using the zsh shell. 
# useful zsh spaceship numeric operator <->
        touch {1..5}.php {6,7,8,12}.php {00..05}.php
        ls <->.php
        ls 0<->.php…

#==============================##==============================#
# CMD ZSH						       #
#==============================##==============================#
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

  █║▌│║█║▌★ KALI ★ PARROT ★ DEBIAN 🔴 PENTESTING ★ HACKING ★ █║▌│║█║▌

              ██╗ ██╗ ██████╗  ██████╗ ██╗  ██╗███████╗██████╗
             ████████╗██╔══██╗██╔═══██╗╚██╗██╔╝██╔════╝██╔══██╗
             ╚██╔═██╔╝██║  ██║██║   ██║ ╚███╔╝ █████╗  ██║  ██║
             ████████╗██║  ██║██║   ██║ ██╔██╗ ██╔══╝  ██║  ██║
             ╚██╔═██╔╝██████╔╝╚██████╔╝██╔╝ ██╗███████╗██████╔╝
              ╚═╝ ╚═╝ ╚═════╝  ╚═════╝ ╚═╝  ╚═╝╚══════╝╚═════╝

               █║▌│║█║▌ WITH COMMANDLINE-KUNGFU POWER █║▌│║█║▌

░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░