| ZSH-LOVERS(1) | ZSH-LOVERS(1) |
نام (NAME)
zsh-lovers - نکتهها، ترفندها و مثالهایی برای Z shell
خلاصه دستور (SYNOPSIS)
فقط آن را بخوانید. ;-)
نمای کلی (OVERVIEW)
هر زمان که به کتابچه راهنمای zsh نگاه میکنیم، در شگفت میشویم که چرا هیچ مثالی یا اینگونه موارد ساده در زندگی (پوستهای) وجود ندارد. پوسته zsh ویژگیهای بسیاری دارد، اما هیچ صفحه راهنمایی همراه با چند مثال (مانند procmailex(5)) برای آن وجود نداشت. به همین دلیل ما این صفحه راهنما را نوشتیم.
بیشتر ترفندها و دستورهای تکخطی از فهرستهای پستی zsh-users، zsh-workers، گوگل، گروههای خبری و خود ما گردآوری شدهاند. برای جزئیات بخش LINKS را ببینید.
نکته: این صفحه راهنما (zsh-lovers(1)) یک بخش رسمی از Z shell نیست! این فقط یک صفحه راهنما صرفاً برای سرگرمی است ;) برای نظرات، گزارش خطاها و بازخوردها نگاهی گذرا به بخش BUGS بیندازید.
اسکریپتنویسی شل (SHELL-SCRIPTING)
این بخش مثالهایی برای موارد پرکاربرد اسکریپتنویسی شل ارائه میدهد. توجه داشته باشید که نباید استفاده کنید در غیر این صورت اغلب مثالها کار نخواهند کرد. تجزیه گزینهها در اسکریپتهای شل. مثالی برگرفته از ZWS توسط Adam Chodorowski (http://www.chodorowski.com/projects/zws):
parse_options()
{
o_port=(-p 9999)
o_root=(-r WWW)
o_log=(-d ZWS.log)
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
fi
port=$o_port[2]
root=$o_root[2]
log=$o_log[2]
if [[ $root[1] != '/' ]]; then root="$PWD/$root"; fi
}
# now use the function:
parse_options $*
مثالها (EXAMPLES)
زیربخشهای موجود عبارتند از Aliases، Completion، Unsorted/Misc examples، (Recursive) Globbing - Examples، Modifiers usage، Redirection-Examples، ZMV-Examples و Module-Examples.
نامهای مستعار (ALIASES)
نامهای مستعار پسوند (Suffix aliases) از نسخه 4.2.0 در zsh پشتیبانی میشوند. چند مثال:
alias -s tex=vim alias -s html=w3m alias -s org=w3m
اکنون فشردن کلید اینتر پس از وارد کردن foobar.tex، ویرایشگر vim را با foobar.tex اجرا میکند. فراخوانی یک فایل html مرورگر w3m را اجرا میکند. وارد کردن www.zsh.org و فشردن کلید اینتر، w3m را با آرگومان www.zsh.org اجرا میکند. نامهای مستعار سراسری (Global aliases) میتوانند در هر کجای خط فرمان استفاده شوند. مثال:
$ alias -g C='| wc -l' $ grep alias ~/.zsh/* C 443
چند نام مستعار سراسری کموبیش کاربردی (انتخاب اینکه برای شما مفید هستند یا نه بر عهده خودتان است):
alias -g ...='../..' alias -g ....='../../..' alias -g .....='../../../..' alias -g CA="2>&1 | cat -A" alias -g C='| wc -l' alias -g D="DISPLAY=:0.0" alias -g DN=/dev/null alias -g ED="export DISPLAY=:0.0" alias -g EG='|& egrep' alias -g EH='|& head' alias -g EL='|& less' alias -g ELS='|& less -S' alias -g ETL='|& tail -20' alias -g ET='|& tail' alias -g F=' | fmt -' alias -g G='| egrep' alias -g H='| head' alias -g HL='|& head -20' alias -g Sk="*~(*.bz2|*.gz|*.tgz|*.zip|*.z)" alias -g LL="2>&1 | less" alias -g L="| less" alias -g LS='| less -S' alias -g MM='| most' alias -g M='| more' alias -g NE="2> /dev/null" alias -g NS='| sort -n' alias -g NUL="> /dev/null 2>&1" alias -g PIPE='|' alias -g R=' > /c/aaa/tee.txt ' alias -g RNS='| sort -nr' alias -g S='| sort' alias -g TL='| tail -20' alias -g T='| tail' alias -g US='| sort -u' alias -g VM=/var/log/messages alias -g X0G='| xargs -0 egrep' alias -g X0='| xargs -0' alias -g XG='| xargs egrep' alias -g X='| xargs'
همچنین ببینید: man 1 zshcompctl zshcompsys zshcompwid. بخش zshcompctl سبک قدیمی تکمیل برنامهپذیر در zsh است، zshcompsys سامانهٔ جدید تکمیل است، و zshcompwid ابزارکهای تکمیل zsh هستند.
برخی توابع مانند _apt و _dpkg بسیار کند هستند. میتوانید برای ذخیره و میانجیگری فهرست نتایج (مانند فهرست بستههای دبیان موجود) از حافظهٔ موقت (cache) استفاده کنید. استفاده از cache:
zstyle ':completion:*' use-cache on zstyle ':completion:*' cache-path ~/.zsh/cache
جلوگیری از تکمیل فایلها یا دایرکتوریهای CVS:
zstyle ':completion:*:(all-|)files' ignored-patterns '(|*/)CVS' zstyle ':completion:*:cd:*' ignored-patterns '(*/)#CVS'
تطبیق فازی (تقریبی) موارد تکمیل برای زمانی که آنها را اشتباه تایپ میکنید:
zstyle ':completion:*' completer _complete _match _approximate zstyle ':completion:*:match:*' original only zstyle ':completion:*:approximate:*' max-errors 1 numeric
و اگر میخواهید تعداد خطاهای مجاز توسط _approximate بر اساس طول متنی که تاکنون تایپ کردهاید افزایش یابد:
zstyle -e ':completion:*:approximate:*' \
max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
نادیدهگرفتن توابع تکمیل برای دستورهایی که در اختیار ندارید:
zstyle ':completion:*:functions' ignored-patterns '_*'
با توابع کمکی مانند:
xdvi() { command xdvi ${*:-*.dvi(om[1])} }
در بسیاری از موارد میتوانید از لزوم تکمیل خودکار بینیاز شوید، اما در صورت نیاز، شاید بخواهید فوراً به انتخاب منویی بروید و کلمات بر اساس زمان مرتب شوند:
zstyle ':completion:*:*:xdvi:*' menu yes select zstyle ':completion:*:*:xdvi:*' file-sort time
تکمیل شناسههای فرایند (PID) با انتخاب منویی:
zstyle ':completion:*:*:kill:*' menu yes select zstyle ':completion:*:kill:*' force-list always
اگر در نهایت از یک دایرکتوری به عنوان آرگومان استفاده کنید، این کار اسلش انتهایی را حذف خواهد کرد (کاربردی برای دستور ln)
zstyle ':completion:*' squeeze-slashes true
دستور cd هرگز دایرکتوری والد را انتخاب نخواهد کرد (مانند: cd ../<TAB>):
zstyle ':completion:*:cd:*' ignore-parents parent pwd
روشی دیگر برای تغییر سریع دایرکتوریها. این قطعهکد را به ~/.zshrc خود بیفزایید، سپس تنها کافی است “cd ..../dir” را وارد کنید
rationalise-dot() {
if [[ $LBUFFER = *.. ]]; then
LBUFFER+=/..
else
LBUFFER+=.
fi
}
zle -N rationalise-dot
bindkey . rationalise-dot
نکته: فهرستی از توصیفکنندههای معتبر تطبیق الگو (glob Qualifiers) را میتوان در zshexpn(1) یافت. برای جزئیات به “man 1 zshexpn | less -p” Qualifiers مراجعه کنید.
# گرفتن نام تمام فایلهایی که در *هیچجای* فایل با الگو مطابقت *ندارند*
# (و بدون استفاده از ``-L'' زیرا مختص گنو است)
$ print -rl -- *(.^e{'grep -q pattern $REPLY'})
# یا
$ : *(.e{'grep -q pattern $REPLY || print -r -- $REPLY'})
# اعداد تصادفی
$ echo $[${RANDOM}%1000] # تصادفی بین 0-999
$ echo $[${RANDOM}%11+10] # تصادفی بین 10-20
$ echo ${(l:3::0:)${RANDOM}} # به طول N رقم (۳ رقم)
# معکوس کردن یک کلمه
$ echo "${(j::)${(@Oa)${(s::):-hello}}}"
# نمایش جدیدترین دایرکتوری
$ ls -ld *(/om[1])
# عنصر تصادفی از آرایه
$ FILES=( .../files/* )
$ feh $FILES[$RANDOM%$#FILES+1]
# خواندن خط اول در تمام فایلهای این دایرکتوری
$ for file (*(ND-.)) IFS= read -re < $file
# بررسی عددی بودن یک پارامتر
$ if [[ $1 == <-> ]] ; then
echo numeric
else
echo non-numeric
fi
# نمایش تمام فایلهای .c که فایل .o متناظر آنها وجود ندارد.
$ print *.c(e_'[[ ! -e $REPLY:r.o ]]'_)
# تمام فایلهای موجود در /var/ که مالک آنها root نیست
$ ls -ld /var/*(^u:root)
# تمام فایلهایی که مالک آنها مجوز خواندن و اجرا دارد
$ echo *(f:u+rx:)
# همانند قبل، اما دیگران مجوز اجرا ندارند
$ echo *(f:u+rx,o-x:)
# بسط آکولاد (brace expansion) - مثال
$ X=(A B C)
$ Y=(+ -)
$ print -r -- $^X.$^Y
A.+ A.- B.+ B.- C.+ C.-
# واکشی جدیدترین فایلی که نامش شامل رشته 'fgractg*.log' است
# و حاوی رشته 'ORA-' در درون خود میباشد
$ file=(fgractg*.log(Nm0om[1]))
$ (($#file)) && grep -l ORA- $file
# بدون Zsh
$ files=$( find . -name . -o -prune -name 'fgractg*>log' -mtime 0 -print )
> if [ -n "$files" ]; then
> IFS='
> '
> set -f
> file=$(ls -td $files | head -1)
> grep -l ORA- "$file"
> fi
# فعال نگهداشتن تعداد مشخصی فرآیند فرزند تا زمان اتمام کل کار
$ zsh -c 'sleep 1 & sleep 3 & sleep 2& print -rl -- $jobtexts'
# حذف فایلهای با اندازه صفر و فایلهای .bak در یک دایرکتوری
$ rm -i *(.L0) *.bak(.)
# چاپ فایلهایی که پسوند ندارند
$ printf '%s\n' ^?*.*
$ printf '%s\n' ^?*.[^.]*(D)
$ ls -d -- ^?*.*(D)
# یافتن فایلهایی که شامل یک رشته خاص نیستند
$ print -rl file* | comm -2 -3 - <(grep -l string file*)'
$ for f (file*(N)) grep -q string $f || print -r $f'
# نمایش/بررسی فعال بودن یا نبودن یک گزینه. هم با $options و هم با $builtins
# کار میکند
$ echo $options[correct]
off
$ $options[zle]
on
# شمارش تعداد دایرکتوریهای روی پشته
$ print $((${${(z)${(f)"$(dirs -v)"}[-1]}[1]} + 1)) # یا
$ dirs -v | awk '{n=$1}END{print n+1}'
# تطبیق تمام فایلهایی که نقطهای در نام خود ندارند
$ ls *~*.*(.)
# نمایش تنها نشانی IP از دستور ``ifconfig device''
# دستور ifconfig از net-tools (در لینوکس)
$ print ${${$(LC_ALL=C /sbin/ifconfig eth0)[7]}:gs/addr://}
# دستور ifconfig از 4.2BSD در {Free,Net,Open}BSD
$ print ${$(/sbin/ifconfig tun0)[6]}
# ارسال پینگ به تمام نشانیهای IP در چند کلاس C یا همه میزبانهای
# داخل /etc/hosts
$ for i in {1..254}; do ping -c 1 192.168.13.$i; done
یا
$ I=1
$ while ( [[ $I -le 255 ]] ) ; do ping -1 2 150.150.150.$I; let I++; done
یا
$ for i in $(sed 's/#.*//' > /etc/hosts | awk '{print $2}')
: do
: echo "Trying $i ... "
: ping -c 1 $i ;
: echo '============================='
: done
# بارگذاری تمام ماژولهای موجود هنگام راهاندازی
$ typeset -U m
$ m=()
$ for md ($module_path) m=($m $md/**/*(*e:'REPLY=${REPLY#$md/}'::r))
$ zmodload -i $m
# تغییر نام تمام فایلهای یک دایرکتوری به گونهای که نام آنها یک پیشوند
# عددی با ترتیب مرتبسازی پیشفرض دریافت کند.
$ 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
# یافتن (و چاپ) تمام پیوندهای نمادین بدون مقصد درون درخت دایرکتوری
# فعلی.
$ $ file **/*(D@) | fgrep broken
$ for i in **/*(D@); [[ -f $i || -d $i ]] || echo $i
$ echo **/*(@-^./=%p)
$ print -l **/*(-@)
# فهرست کردن تمام فایلهای عادی که پسوند آنها در `fignore' فهرست نشده است
$ ls **/*~*(${~${(j/|/)fignore}})(.)
# مانند بالا، اما با حذف فایلهای اجرایی
$ ls **/*~*(${~${(j/|/)fignore}})(.^*)
# چاپ فایلهایی که پسوند ندارند (نیازمند *setopt extendedglob*
# و *setopt dotglob*)
$ printf '%s\n' ^?*.*
# فهرست کردن فایلها به ترتیب معکوسِ مرتبشده بر اساس نام
$ print -rl -- *(On)
یا
$ print -rl -- *(^on)
# معادل دستور ``ps ax | awk '{print $1}'''
$ print -l /proc/*/cwd(:h:t:s/self//)
# دریافت PID یک فرآیند (بدون استفاده از ``ps''، ``sed''، ``pgrep'' و ..
# در لینوکس)
$ pid2 () {
> local i
> for i in /proc/<->/stat
> do
> [[ "$(< $i)" = *\((${(j:|:)~@})\)* ]] && echo $i:h:t
> done
> }
# برای X در 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y'؛ do ...
$ for (( i = 36#n; i <= 36#y; i++ )); do
> print ${$(([##36]i)):l}
> done
# یا در ترکیب با ``dc''
$ print {$((##n))..$((##y))}P\ 10P | dc
# یا با استفاده از ``eval''
$ eval print '${$(([##36]'{$((36#n))..$((36#y))}')):l}'
# دستور foreach در یک خط شل
$ for f (*) print -r -- $f
# کپی بازگشتی یک دایرکتوری بدون دادهها/فایلها
$ dirs=(**/*(/))
$ cd -- $dest_root
$ mkdir -p -- $dirs
# یا بدون zsh
$ find . -type d -exec env d="$dest_root" \
sh -c ' exec mkdir -p -- "$d/$1"' '{}' '{}' \;
# اگر `foo=23'' باشد، چاپ در ۱۰ رقم با پیشوند '0'.
$ foo=23
$ print ${(r:10::0:)foo}
# یافتن نام تمام فایلهای موجود در دایرکتوری خانگی که نام آنها
# ۲۰ نویسه یا بیشتر دارد
print -rl $HOME/${(l:20::?:)~:-}*
# ذخیره آرایهها
$ print -r -- ${(qq)m} > $nameoffile # ذخیره آن
$ eval "m=($(cat -- $nameoffile)" # یا استفاده از
$ m=("${(@Q)${(z)"$(cat -- $nameoffile)"}}") # برای بازیابی آن
# گرفتن خروجی "ls -l" برای تمام فایلهای درخت که سن آنها کمتر از یک
# مقدار مشخص است (مثلاً "ls -l" تمام فایلهای درخت که در ۲ روز
# گذشته تغییر یافتهاند)
$ ls -tld **/*(m-2)
# این دستور فهرستی با ۱ فایل در هر خط ارائه میدهد (نه به سبک ls -R).
# روشی ساده برای داشتن خروجی سبک "ls -R" تنها با فایلهایی
# که جدیدتر از ۲ روز هستند.
$ for d (. ./**/*(/)) {
> print -r -- $'\n'${d}:
> cd $d && {
> l=(*(Nm-2))
> (($#l)) && ls -ltd -- $l
> cd ~-
> }
> }
# اگر میخواهید دایرکتوریها نیز حتی در صورت بیشتر بودن mtime آنها
# از ۲ روز گنجانده شوند:
$ for d (. ./**/*(/)) {
> print -r -- $'\n'${d}:
> cd $d && {
> l=(*(N/,m-2))
> (($#l)) && ls -ltd -- $l
> cd ~-
> }
> }
# و اگر میخواهید تنها دایرکتوریهایی با mtime < 2 روز فهرست شوند:
$ for d (. ./**/*(N/m-2)) {
> print -r -- $'\n'${d}:
> cd $d && {
> l=(*(Nm-2))
> (($#l)) && ls -ltd -- $l
> cd ~-
> }
> }
# چاپ ۴۲ نویسه ``-''
$ echo ${(l:42::-:)}
# یا استفاده از ``$COLUMS''
$ echo ${(l:$COLUMNS::-:)}
# و اکنون با رنگها (نیازمند autoload colors ;colors)
$ echo "$bg[red]$fg[black]${(l:42::-:)}"
# تغییر مسیر STDERR به دستوری مانند xless بدون تغییر مسیر همزمان STDOUT.
$ foo 2>>(xless)
# اما این دستور به صورت ناهمگام اجرا میشود. برای اجرای همگام آن:
$ { { foo 1>&3 } 2>&1 | xless } 3>&1
# تغییر نام تمام فایلهای MP3 از name with spaces.mp3 به Name With Spaces.mp3
$ for i in *.mp3; do
> mv $i ${${(C)i}:s/Mp3/mp3/}
> done
# تطبیق نام فایلهایی که فقط شامل رقم بوده و به .xml ختم میشوند (نیازمند
# *setopt kshglob*)
$ ls -l [0-9]##.xml
$ ls -l <0->.xml
# حذف تمام فایلهای غیر متنی ("غیر txt")
$ rm ./^*.txt
# انتقال ۲۰۰ فایل از یک دایرکتوری به دایرکتوری دیگر
$ mv -- *([1,200]) /another/Dir
# تبدیل تصاویر (foo.gif => foo.png):
$ for i in **/*.gif; convert $i $i:r.png
# تبدیل مجموعهای از فایلهای mp3 به wave یا cdr،
# (مثلاً file.wav -> file.mp3)
$ for i (./*.mp3){mpg321 --w - $i > ${i:r}.wav}
# بارگیری فایلهای ایجادشده با LaTeX2HTML (برای مثال ZSH-Guide):
$ for f in https://zsh.sourceforge.io/Guide/zshguide{,{01..08}}.html; do
> lynx -source $f >${f:t}
> done
# انتقال تمام فایلهای dir1 و dir2 که تعداد خطوط آنها بیشتر از ۱۰ است به
# دایرکتوری دیگر، مثلاً "/more10"
$ mv dir[12]/**/*.cr(-.e{'((`wc -l < $REPLY` > 10))'}) /more10
# ساخت یک فهرست کامل از تمام فایلهای نصبشده توسط dpkg
$ diff <(find / | sort) <(cat /var/lib/dpkg/info/*.list | sort)
# جایگزینی این توالیهای گریز (Escape-Sequences) لعنتی:
$ autoload colors ; colors
$ print "$bg[cyan]$fg[blue]You are a idiot" >> /dev/pts/3
# دریافت مقدار ASCII یک نویسه
$ char=N ; print $((#char))
# پسوند فایل ("Erweiterung")
# نکته: علامت (N) مشخص میکند که گزینه nullglob برای این الگوی خاصِ
# تطبیق (glob pattern) اعمال شود.
$ for i in *.o(N); do
> rm $i
> done
# تغییر نام فایلها؛ یعنی FOO به foo و bar به BAR
$ for i in *(.); mv $i ${i:l} # `FOO' به `foo'
$ for i in *(.); mv $i ${i:u} # `bar به `BAR'
# نمایش تمام فایلهای suid در $PATH
$ ls -latg ${(s.:.)PATH} | grep '^...s'
# یا حالتی پیچیدهتر ;)
$ print -l ${^path}/*(Ns,S)
# یا فقط نمایش فایلهای اجرایی مطابق با الگوی مشخصشده توسط کاربر
$ print -l ${^path}/*vim*(*N)
# فشردهسازی با gzip در صورت حاوی بودن یک رشته مشخص
$ gzip ${(ps:\0:)"$(grep -lZ foobar ./*.txt(.))"}
# یک تکخطی کوتاه که از stdin خوانده و اولین خط یکتا را در stdout چاپ میکند؛
# یعنی خطوطی که قبلاً چاپ شدهاند را دوباره چاپ نمیکند (مشابه دستور unique،
# اما unique فقط خطوط مجاور را پردازش میکند).
$ IFS=$'\n\n'; print -rl -- ${(Oau)${(Oa)$(cat file;echo .)[1,-2]}}
# فهرست کردن تمام فایلهای اجرایی در PATH
$ print -l ${^path}/*(-*N)
# تطبیق تمام فایلهای .c در همه زیردایرکتوریها، _بهجز_ زیردایرکتوریهای SCCS؟
$ ls **/*.c~(*/)#SCCS/*
# فهرست کردن تمام فایلهای `README' بدون حساسیت به حروف کوچک و بزرگ و با حداکثر یک غلط املایی
$ ls **/*(#ia2)readme
# بررسی متغیرها بدون حساسیت به حروف کوچک و بزرگ
$ if [[ $OSTYPE == (#i)LINUX*(#I) ]]; then
> echo "Penguin on board."
> else
> echo "Not a Linux."
> fi
فهرستی از توصیفکنندههای معتبر تطبیق الگو (glob Qualifiers) را میتوانید در zshexpn(1) بیابید. نکته: **/ معادل (*/)#! است! برای مثال:
$ print (*/)#zsh_us.ps zsh-4.2.3/Doc/zsh_us.ps $ print **/zsh_us.ps zsh-4.2.3/Doc/zsh_us.ps
# جستجو برای `README' در تمامی زیردایرکتوریها
$ ls -l **/README
# یافتن دایرکتوریهایی که شامل هر دو فایل "index.php" و "index.html" هستند، یا بهطور
# کلی، دایرکتوریهایی که شامل بیش از یک فایل منطبق با "index.*" باشند
$ ls **/*(D/e:'[[ -e $REPLY/index.php && -e $REPLY/index.html ]]':)
# یا
$ ls **/*(D/e:'l=($REPLY/index.*(N)); (( $#l >= 2 ))':)
# دستور find برای جستجو بر اساس نام دایرکتوری به جای basename
$ print -rl /**/*~^*/path(|/*)
# یا - بدون Zsh
$ find / | grep -e /path/ -e '/path$'
# چاپ مسیر دایرکتوریهایی که ۱۰ فایل عادی بزرگ C را
# در دایرکتوری جاری و زیردایرکتوریها نگهداری میکنند.
$ print -rl -- **/*.c(D.OL[1,10]:h) | sort -u
# یافتن فایلهایی با اندازه == 0 و ارسال ایمیل
$ files=(**/*(ND.L0m+0m-2))
> (( $#files > 0 )) && print -rl -- $files | \
mailx -s "empty files" foo@bar.tdl
# اجرای بازگشتی chmod
$ chmod 700 **/(.) # فقط فایلها
$ chmod 700 **/(/) # فقط دایرکتوریها
# چاپ تمام فایلهای آن دایرکتوری در ۲ ستون
$ print -rC2 -- ${1:[...]}/*(D:t)
# ^- تعداد ستونها
# یا - در صورت نگرانی درباره نویسههای خاص - استفاده کنید از
$ list=(${1:[...]}/*(ND:t))
$ (($#list)) && print -rC2 -- ${(V)list}
# جستجوی همه فایلها در /home/*/*-mail/ با پرچم تنظیمشده ``chmod -s''
# (بازگشتی، شامل dotfileها)، حذف پرچم setgid/setuid و چاپ
# یک پیام
$ chmod -s /home/*/*-mail(DNs,S) /home/*/*-mail/**/*(DNs,S))
# یا با یک اسکریپت کوچک
$ for file (/home/*/*-mail(DNs,S) /home/*/*-mail/**/*(DNs,S)) {
> print -r -- $file
> chmod -s $file && print -r fixed $file
> }
# یا استفاده از ``zargs'' (نیازمند autoload zargs) برای جلوگیری از خطای
# arg list too long
$ zargs /home/*/*-mail(DNs,S) /home/*/*-mail/**/*(DNs,S)) -- chmod -s
# فهرست کردن فایلها از `foo23' به بالا (foo23، foo24، foo25، ..)
$ ls -l foo<23->
# دریافت همه فایلهایی که با رشتههای تاریخ از ۴ ژوئن تا
# ۹ ژوئن ۲۰۰۴ آغاز میشوند
$ ls -l 200406{04..10}*(N)
# یا اگر به فرم 200406XX باشند (نیازمند ``setopt extended_glob'')
$ ls -l 200306<4-10>.*
# حذف فاصلهها از نام فایلها
$ for a in ./**/*\ *(Dod); do mv $a ${a:h}/${a:t:gs/ /_}; done
# نمایش فقط همه فایلهای *.c و *.h
$ ls -l *.(c|h)
# نمایش فقط همه فایلهای *.c و نادیده گرفتن `foo.c'
$ ls *.c~foo.c
# نمایش دادهها در قالب *واقعاً* باینری
$ zsh -ec 'while {} {printf %.8x $n;repeat 8 \
> {read -ku0 a printf \ %.8d $(([##2]#a))};print;((n+=8))}' < binary
# نمایش فقط فایلهای قابل خواندن توسط همگان (world-readable)
$ ls -l *(R)
# فهرست کردن فایلهایی در دایرکتوری جاری که توسط مالک قابل نوشتن نیستند
$ print -l ~/*(ND.^w)
# یافتن و حذف فایلهایی که از یک مقدار مشخص قدیمیتر هستند
# (ثانیه/دقیقه/ساعت)
# حذف تمام فایلهای عادی در /Dir که قدیمیتر از ۳ ساعت هستند
$ rm -f /Dir/**/*(.mh+3)
# حذف تمام پیوندهای نمادین در /Dir که قدیمیتر از ۳ دقیقه هستند
$ rm -f /Dir/**/*(@mm+3)
# حذف تمام موارد غیردایرکتوری در /Dir که قدیمیتر از ۳۰ ثانیه هستند
$ rm -f /Dir/**/*(ms+30^/)
# حذف تمام پوشهها، زیرپوشهها و فایلهای قدیمیتر از یک ساعت
$ rm ./**/*(.Dmh+1,.DL0)
# حذف تمام فایلهای قدیمیتر از ۶ ساعت
$ rm -f **/*(mh+6)
# حذف تمام فایلها به جز ۱۰ فایل جدیدتر (حذف همه به جز ۱۰ فایل
# آخر در یک دایرکتوری)
$ rm ./*(Om[1,-11])
نکته: اگر با خطای arg list too long مواجه شدید، از rm توکار استفاده کنید. برای
مثال:
$ zmodload zsh/files ; rm -f **/*(mh+6)
یا از تابع zargs استفاده کنید:
$ autoload zargs ; zargs **/*(mh+6) -- rm -f
# راهنمای کاربر Z-Shell / بخش ۵.۹: تولید نام فایل و تطبیق الگو؛
# یافتن بازگشتی همه فایلها در تمام زیردایرکتوریها که دارای نام مشخصی هستند،
# بدون حساسیت به حروف بزرگ و کوچک، با اندازه حداقل 50 KB، با قدمت حداکثر یک هفته
# و متعلق به کاربر root، همراه با مجاز بودن حداکثر یک خطا در املای نام.
# در واقع، عبارت مورد نیاز به این شکل است:
$ ls **/(#ia1)name(LK+50mw-1u0)
# تغییر UID از 102 به 666
$ chown 666 **/*(u102)
# فهرست کردن همه فایلهایی که در ۱۰ ساعت گذشته بهروزرسانی نشدهاند
$ print -rl -- *(Dmh+10^/)
# حذف فقط قدیمیترین فایل در یک دایرکتوری
$ rm ./*filename*(Om[1])
# مرتبسازی خروجی `ls -l' بر اساس اندازه فایل
$ ls -fld *(OL)
# یافتن جدیدترین فایل در یک دایرکتوری
$ setopt dotglob ; print directory/**/*(om[1])
# نمایش فقط فایلهای خالی که نه برای گروه و نه همگان قابل نوشتن هستند
$ ls *(L0f.go-w.)
# یافتن - و فهرست کردن - ۱۰ تا از جدیدترین فایلها در دایرکتوریها و زیردایرکتوریها.
# (بازگشتی)
$ print -rl -- **/*(Dom[1,10])
# چاپ تنها ۵ خط توسط دستور "ls" (مشابه ``ls -laS | head -n 5'').
$ ls -fl *(DOL[1,5])
# نمایش ۵ تا ۱۰ فایل با آخرین تغییرات.
$ print -rl -- /path/to/dir/**/*(D.om[5,10])
# یافتن همه فایلهای فاقد مالک معتبر.
$ chmod someuser /**/*(D^u:${(j.:u:.)${(f)"$(</etc/passwd)"}%%:*}:)
# یافتن همه دایرکتوریهای خالی در یک درخت دایرکتوری.
$ for f in ***/*(/l2); do foo=($f/*(N)); [[ -z $foo ]] && print $f; done
# نکته: از نسخه Zsh 4.2.1 توصیفکننده glob با شناسه F نشاندهنده دایرکتوری غیرخالی است.
# بنابراین *(F) نشاندهنده تمام زیردایرکتوریهای دارای ورودی است و *(/^F) به معنای همه
# زیردایرکتوریهای بدون ورودی است.
$ ls -ld *(/^F)
# حذف دایرکتوریهای خالی پس از آن.
$ rmdir ./**/*(/od) 2> /dev/null
# نمایش فقط فایلهایی که متعلق به گروه `users' هستند.
$ ls -l *(G[users])
تغییردهندهها (Modifiers) سازوکاری قدرتمند هستند که به شما امکان میدهند نتایج حاصل از گسترش پارامتر (parameter expansion)، گسترش نام فایل (filename expansion) و گسترش تاریخچه (history expansion) را تغییر دهید. برای جزئیات بیشتر zshexpn(1) را ببینید.
# نکته: به Zsh 4.3.4 نیاز است!
$ autoload -U age
# فایلهای ویرایششده در امروز
$ print *(e:age today now:)
# فایلهای ویرایششده از ساعت ۱۷ به بعد
$ print *(e-age 17:00 now-)
# ... از ساعت ۱۷ دیروز به بعد
$ print *(e-age yesterday,17:00 now-)
# ... از کریسمس گذشته تا پیش از امروز
$ print *(e-age 2006/12/25 today-)
# ... پیش از دیروز
$ print *(e-age 1970/01/01 yesterday-)
# تمام فایلهای ویرایششده میان آغاز آن تاریخها
$ print *(e:age 2006/10/04 2006/10/09:)
# تمام فایلهای ویرایششده در آن تاریخ
$ print *(e:age 2006/10/04:)
# تعیین زمان دقیق.
$ print *(e-age 2006/10/04:10:15 2006/10/04:10:45-)
# حذف آخرین بخش مسیر و باقی گذاشتن بخش ابتدایی (head). عملکردی مشابه
# `dirname' دارد.
$ echo =ls(:h)
/bin
# حذف تمام بخشهای ابتدایی مسیر و باقی گذاشتن انتها (tail). عملکردی مشابه
# `basename' دارد.
$ echo =ls(:t)
ls
# حذف پسوند از هر فایل (در این مثال *.sh)
$f:e پسوند فایل $f است
:h --> سر/مسیر والد (dirname)
:t --> انتها/نام فایل (basename)
:r --> بقیه (حذف پسوند)
$ for f (*.sh) mv $f $f:r
# حذف پسوند فایل به شکل `.xxx' و باقی گذاشتن نام پایه.
$ echo $PWD
/usr/src/linux
$ echo $PWD:t
linux
# حذف همهچیز بهجز پسوند.
$ foo=23.42
$ echo $foo
23.42
$ echo $foo:e
42
# چاپ دستور جدید بدون اجرای آن. فقط با گسترش تاریخچه (history expansion)
# کار میکند.
$ echo =ls(:h)
/bin
$ !echo:p
$ echo =ls(:h)
# نقلقولگذاری کلمات جایگزینشده و گریز از جایگزینیهای بعدی.
$ bar="23'42"
$ echo $bar
23'42
$ echo $bar:q
23\'42
# تبدیل تمام حروف کلمات به حروف کوچک.
$ bar=FOOBAR
$ echo $bar
FOOBAR
$ echo $bar:l
foobar
# تبدیل تمام حروف کلمات به حروف بزرگ.
$ bar=foobar
$ echo $bar
foobar
$ echo $bar:u
FOOBAR
# تبدیل نخستین نویسه هر کلمه به حروف بزرگ
$ foo="one two three four"
$ print -r -- "${(C)foo}"
One Two Three Four
مثالهای بازهدایت (Redirection-Examples)
برای اطلاعات بیشتر zshmisc(1) را ببینید (یا دستور less ${^fpath}/zmv(N))
# الحاق `exit 1' به انتهای تمام فایلهای *.sh
$ echo "exit 1" >> *.sh
# افزودن فایلها به foobar.tar.gz
$ eval set =(gunzip < foobar.tar.gz) '
tar rf $1 additional.txt &&gzip < $1 > foobar.tar.gz'
# بازهدایت خروجی به یک فایل و نمایش همزمان آن روی صفحه
$ foobar >&1 > file1 > file2 > ..
# هدایت خروجی واحد با لولهکشی (pipe) به چندین ورودی
$ zcat foobar.Z >> (gzip -9 > file1.gz) \
>> (bzip2 -9 > file1.bz2) \
>> (acb --best > file1.acb)
# الحاق /etc/services به انتهای فایلهای `foo' و `bar'
$ cat /etc/services >> foo >> bar
# لولهکشی STDERR (خطای استاندارد)
$ echo An error >&2 2>&1 | sed -e 's/A/I/'
# ارسال خروجی استاندارد یک فرایند به ورودی استاندارد چندین فرایند
# در خط لوله
$ setopt multios
$ process1 > >(process1) > >(process2)
# مقداردهی اولیه یک متغیر همزمان با حفظ خروجی ترمینال
$ setopt multios
$ { a=$(command >&1 >& 3 3 > &- 2>&1);} 3>&1
# دو بار بازهدایت stderr
$ setopt multios ; program 2> file2 > file1 2>&1
# تکثیر stdout و stderr در یک فایل لاگ
$ exec 3>&1 > logfile 2>&2 2>&1 >&3 3>&-
# بازهدایت stderr (تنها) به یک فایل و به stderr اصلی:
$ command 2>&2 2>stderr
# بازهدایت stderr و stdout به فایلهای جداگانه و هر دو به stdout اصلی:
$ command 2>&1 1>&1 2>stderr 1>stdout
# بازهدایت stderr و stdout به فایلهای جداگانه، و stdout به stdout اصلی
# و stderr به stderr اصلی:
$ command 2>&2 1>&1 2>stderr 1>stdout
# کارهای جالبتر با STDERR ;)
$ ./my-script.sh 2> >(grep -v moron >error.log)|process-output >output.log
$ echo "Thats STDOUT" >>(sed 's/stdout/another example/' > foobar)
نکته: -n به معنای عدم اجرا است (تنها آنچه اتفاق خواهد افتاد را نمایش میدهد).
# حذف نویسههای غیرمجاز در یک سیستمفایل fat32. نویسههای غیرمجاز عبارتند از:
# / : ; * ? " < > |
# نکته: ``-Q'' و (D) برای گنجاندن فایلهای پنهان است.
$ unwanted='[:;*?\"<>|]'
$ zmv -Q "(**/)(*$~unwanted*)(D)" '$1${2//$~unwanted/}'
# تغییر بخشی از نام فایل (به عنوان مثال "file-hell.name" -> "file-heaven.name")
$ zmv '(*)hell(*)' '${1}heaven${2}'
# یا
$ zmv '*' '$f:s/hell/heaven/'
# حذف پرانتزها در نامهای فایل
# به عنوان مثال foo-(bar).avi -> foo-bar.avi
$ zmv '*' '${f//[()]/}'
# شمارهگذاری ترتیبی تمام فایلها (foo.foo > 1.foo, fnord.foo > 2.foo, ..)
$ autoload zmv
$ ls *
1.c asd.foo bla.foo fnord.foo foo.fnord foo.foo
$ c=1 zmv '*.foo' '$((c++)).foo'
$ ls *
1.c 1.foo 2.foo 3.foo 4.foo foo.fnord
# تغییر نام "file.with.many.dots.txt" با جایگزینی نقطهها (به جز آخرین
# مورد!) با یک فاصله
$ touch {1..20}-file.with.many.dots.txt
$ zmv '(*.*)(.*)' '${1//./ }$2'
# حذف ۴ نویسه نخست از یک نام فایل
$ zmv -n '*' '$f[5,-1]' # نکته: عدد "5" اشتباه نگارشی نیست!
# تغییر نام تمام فایلهای موجود در دایرکتوری جاری به حروف کوچک، با حفظ
# نام دایرکتوریها به همان صورت قبلی.
$ zmv -Qv '(**/)(*)(.D)' '$1${(L)2}'
# جایگزینی همه نویسههای چهارم که "1" هستند با "2" و الی آخر
$ autoload -U zmv
$ zmv '(???)1(???[1-4].txt)' '${1}2${2}'
# حذف ۱۵ نویسه نخست از یک رشته
$ touch 111111111111111{a-z}
$ autoload zmv
$ zmv '*' '$f[16,-1]'
# جایگزینی فاصلهها (به هر تعداد) با یک خط تیره در نام فایلها
$ autload zmv
$ zmv -n '(**/)(* *)' '$1${2//( #-## #| ##)/-}'
# یا - با Bash
$ find . -depth -name '* *' -exec bash -c '
> shopt -s extglob
> file=$1
> dir=${file%/*}
> name=${file##*/}
> newname=${name//*([ -]) *([ -])/-}
> mv -i -- "$file" "$Dir/$newname"' {} {} \;
# پاکسازی نام فایلها و حذف نویسههای خاص
$ autoload zmv
$ zmv -n '(**/)(*)' '$1${2//[^A-Za-z0-9._]/_}'
# افزودن *.py به مجموعهای از اسکریپتهای python در یک دایرکتوری (برخی از آنها به
# *.py ختم میشوند) و دادن یک پسوند مناسب به همه آنها
$ autoload zmv
$ zmv -n '(**/)(con*)(#qe,file $REPLY | grep "python script",)' '$1$2.py'
# تبدیل همه پسوندها به حروف کوچک (به عنوان مثال *.JPG) به همراه زیرپوشهها
$ autoload zmv
$ zmv '(**/)(*).(#i)jpg' '$1$2.jpg'
# یا - بدون Zsh
$ find Dir -name '*.[jJ][pP][gG]' -print | while read f
> do
> case $f in
> *.jpg) ;
> *) mv "$f" "${f%.*}.jpg" ;
> esac
> done
# حذف صفرهای ابتدایی از پسوند فایل
$ autoload zmv
$ ls
filename.001 filename.003 filename.005 filename.007 filename.009
filename.002 filename.004 filename.006 filename.008 filename.010
$ zmv '(filename.)0##(?*)' '$1$2'
$ ls
filename.1 filename.10 filename.2 filename.3 filename.4 filename.5 ..
# شمارهگذاری مجدد فایلها.
$ 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 ...
# افزودن صفرهای پیشین به نام فایل (1.jpg -> 001.jpg, ..
$ autoload zmv
$ zmv '(<1->).jpg' '${(l:3::0:)1}.jpg'
# مانند بالا، اما اکنون فقط برای فایلهایی با نام فایل >= ۳۰ نویسه
$ autoload zmv
$ c=1 zmv "${(l:30-4::?:)}*.foo" '$((c++)).foo'
# جایگزینی فاصلهها در نام فایلها با خط زیرین (underline)
$ autoload zmv
$ zmv '* *' '$f:gs/ /_'
# تغییر پسوند از *.sh به *.pl
$ autoload zmv
$ zmv -W '*.sh' '*.pl'
# افزودن پسوند ".txt" به تمام فایلهای درون ${HOME}
# ``-.'' فقط برای تغییر نام فایلهای عادی یا پیوندهای نمادین به فایلهای عادی است،
# ``D'' برای تغییر نام فایلهای پنهان (dotfiles) نیز هست)
$ autoload zmv
$ zmv -Q '/home/**/*(D-.)' '$f.txt'
# یا فقط برای تغییر نام فایلهایی که پسوند ندارند:
$ zmv -Q '/home/**/^?*.*(D-.)' '$f.txt'
# تغییر نام فایلهای دارای نویسههای ? [ ] / = + < > ; : " , - * به صورت بازگشتی
$ autoload zmv
$ chars='[][?=+<>;",*-]'
$ zmv '(**/)(*)' '$1${2//$~chars/%}'
# حذف علامت نقلقول تکی از نام فایلها (به صورت بازگشتی)
$ autoload zmv
$ zmv -Q "(**/)(*'*)(D)" "\$1\${2//'/}"
# وقتی فایل جدیدی وارد میشود (به نام file.txt)، تغییر نام همه فایلها به ترتیبی
# که مثلاً file119.txt به file120.txt تبدیل شود، file118.txt به
# file119.txt تبدیل شود و به همین ترتیب file.txt به file1.txt تبدیل گردد
$ autoload zmv
$ zmv -fQ 'file([0-9]##).txt(On)' 'file$(($1 + 1)).txt'
# تبدیل همه فایلها/دایرکتوریها به حروف کوچک/بزرگ
$ autoload zmv
$ zmv '(*)' '${(L)1}' # حروف کوچک
$ zmv '(*)' '${(U)1}' # حروف بزرگ
# حذف پسوند *.c از تمام فایلهای C
$ autoload zmv
$ zmv '(*).c' '$1'
# بزرگ کردن تنها حرف اول تمام فایلهای *.mp3
$ autoload zmv
$ zmv '([a-z])(*).mp3' '${(C)1}$2.mp3'
# رونوشت از فایل مقصد `README' در همان دایرکتوریِ هر `Makefile'
$ autoload zmv
$ zmv -C '(**/)Makefile' '${1}README'
# حذف علامت نقلقول تکی از نام فایلها (به صورت بازگشتی)
$ autoload zmv
$ zmv -Q "(**/)(*'*)(D)" "\$1\${2//'/}"
# تغییر نام pic1.jpg، pic2.jpg، .. به pic0001.jpg، pic0002.jpg، ..
$ autoload zmv
$ zmv 'pic(*).jpg' 'pic${(l:4::0:)1}.jpg'
$ zmv '(**/)pic(*).jpg' '$1/pic${(l:4::0:)2}.jpg' # به صورت بازگشتی
لطفاً ابتدا zshmodules(1) را بخوانید!
zsh/pcre
(نیازمند zmodload
zsh/pcre)
# رونوشت از پروندههای یک بازه زمانی خاص (تاریخ در نام پروندهها ذکر شده است)
$ zmodload zsh/pcre
$ ls -d -- *(e:'[[ $REPLY -pcre-match pcre-regexp ]]':)
# یا
$ m() { [[ $1 -pcre-match pcre-regexp ]] }
$ ls -d -- *(+m)
zsh/clone
(نیازمند zmodload
zsh/clone)
# یک نمونه انشعابیافته (forked) از پوسته جاری ایجاد کرده ($! برابر صفر تنظیم میشود) و # دستور ``command'' را روی /dev/tty8 (برای این مثال) اجرا میکند. $ zmodload zsh/clone $ clone /dev/tty8 && (($! == 0)) && exec command
zsh/datetime
(نیازمند zmodload
zsh/datetime)
$ zmodload zsh/datetime
$ alias datereplacement='strftime "%Y-%m-%d" $EPOCHSECONDS'
$ export DATE=`datereplacement`
$ echo $DATE
# حذف تاریخ از نام پرونده
$ $ zmodload zsh/datetime
$ setopt extendedglob
$ touch aaa_bbb_20041212_c.dat eee_fff_20051019_g.dat
$ 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
???_???_<0-20050815>_?.dat
# جستجوی پروندههای با اندازه == 0، بر اساس نام پرونده که شامل تاریخ است
# به جای تاریخ «آخرین تغییر» (last modified) پرونده
$ 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
(نیازمند zmodload
zsh/stat)
# بررسی اینکه آیا یک پیوند نمادین به پرونده خاصی پیوند دارد یا خیر
$ zmodload -i zsh/stat
$ ! stat -LH s foo.ln || [[ $s[link] != "foo.exe" ]] || ln -sf foo.exe foo.ln
# مقایسه تاریخ پروندهها
$ zmodload zsh/stat
$ file1=foo
$ file2=bar
$ touch bar & sleep 5 & touch foo
$ echo $file1 is $(($(stat +mtime $file2) - \
$(stat +mtime $file1))) seconds older than $file2.
bar is 5 seconds older than foo
# فهرست کردن پروندههای یک دیسک که از یک پرونده دیگر کوچکتر هستند
$ zmodload zsh/stat
$ stat -A max +size some-other-file
$ print -rl ./**/*(D.L-$max)
# فهرست کردن ۱۰۰ پرونده بزرگ در یک دیسک
$ zmodload zsh/stat
$ ls -fld ./**/*(d`stat +device .`OL[1,100])
# دریافت فقط نام کاربری و نامهای پرونده از (مانند
# ls -l * | awk '{print $3" " $8}')
$ zmodload zsh/stat
$ for file; do
> stat -sA user +uid -- "$file" &&
> print -r -- "$user" "$file"
> done
# دریافت تفاوت بین بایتهای واقعی پرونده و بایتهای تخصیصیافته به آن
$ zmodload zsh/stat
$ print $(($(stat +block -- file) * 512 - $(stat +size -- file)))
# یافتن بزرگترین پرونده
# ``D'' : برای لحاظ کردن پروندههای پنهان/نقطهای (d کوچک برای دستگاه است)
# ``O'' : مرتبسازی معکوس (o کوچک برای مرتبسازی عادی است)
# ``L'' : بر اساس اندازه پرونده (l برای تعداد پیوندها است)
# ``[1]'': فقط اولین مورد را برمیگرداند
$ zmodload zsh/stat
$ stat +size ./*(DOL[1])
# اندازه پرونده به بایت
$ zmodload zsh/stat
$ stat -L +size ~/.zshrc
4707
# حذف پروندهها در یک دایرکتوری که در ده روز گذشته به آنها دسترسی نشده است
# و ارسال یک رایانامه به مالک پروندهها برای اطلاع از حذف پروندهها.
$ 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}
# اجرای "ls -l" روی تمام پروندههای درخت که جدیدتر از یک
# سن مشخص هستند
$ zmodload zsh/stat
$ for d (. ./**/*(N/m-2))
> print -r -- $'\n'$d: && cd $d && {
> for f (*(Nm-2om))
> stat -F '%b %d %H:%M' -LsAs -- $f &&
> print -r -- $s[3] ${(l:4:)s[4]} ${(l:8:)s[5]} \
> ${(l:8:)s[6]} ${(l:8:)s[8]} $s[10] $f ${s[14]:+-> $s[14]}
> cd ~-
> }
# دریافت تاریخ ایجاد پرونده
$ zmodload zsh/stat
$ stat -F '%d %m %Y' +mtime ~/.zshrc
30 06 2004
$ stat -F '%D' +mtime ~/.zshrc
06/30/04
zsh/files
(نیازمند zmodload
zsh/files)
# جستجوی یک دایرکتوری برای پروندههای حاوی یک رشته خاص و سپس رونوشت آن # پروندهها به یک دایرکتوری دیگر. $ zmodload zsh/files $ IFS=$'\0' $ cp $(grep -lZr foobar .) otherdirectory
zsh/mapfile
(نیازمند zmodload
zsh/mapfile)
# جستجو برای دو الگو با grep
$ zmodload zsh/mapfile
$ pattern1="foo"
$ pattern2="bar foo"
$ print -l ./**/*(DN.e{'z=$mapfile[$REPLY] && [[ $z = *$pattern1* && \
$z = *$pattern2* ]]'})
# یا راهکاری در ترکیب با zsh/pcre
$ zmodload -i zsh/mapfile zsh/pcre
$ pattern1="foo"
$ pattern2="bar foo"
$ pcre_compile "(?s)(?=.*?$pattern1).*?$pattern2"
$ pcre_study
$ print -l ./**/*(DN.e{'pcre_match $mapfile[$REPLY]'})
# معادل ``less /etc/passwd | grep -v root''
$ zmodload zsh/mapfile
$ IFS=$'\n\n'
$ print -rl -- ${${=mapfile[/etc/passwd]}:#*root*}
# یا - بدون حساسیت به بزرگی و کوچکی حروف
$ setopt extendedglob
$ print -rl -- ${${=mapfile[/etc/passwd]}:#*(#i)root*}
# اگر یک پرونده XML شامل مواردی مانند ``<TAGA/>'' و ``<TAGB/>'' باشد، شمارهگذاری
# این برچسبهای خالی (آنهایی که به '/>' ختم میشوند) تا در صورت مواجهه با همان
# ترتیب، برچسبهای پیشین تبدیل شوند به ``<TAGA/>1</TAGA>'' و
# ``<TAGB/>2</TAGB>''
$ zmodload zsh/mapfile
$ cnt=0
$ apfile[data.xml.new]=${(S)mapfile[data.xml]//\
> (#im)<TAGA>*<\/TAGA>/<TAGA>$((++cnt))<\/TAGA>}
# حذف تمامی پروندهها در Maildir/new کاربران که شامل ``filename="gone.src'' هستند
$ zmodload zsh/{files,mapfile}
$ rm -f /u1/??/*/Maildir/new/100*(.e{'[[ $mapfile[$REPLY] == \
*filename=\"gone.scr\"* ]]'})
# استخراج عنوان (Title) از یک پرونده postscript با grep و الحاق آن مقدار به
# انتهای نام پرونده
$ autoload -U zmv
$ zmodload zsh/mapfile
$ zmv '(*).ps' '$1-${${${mapfile[$f]##*%%Title: }%% *}//[^a-zA-Z0-9_]/}.ps'
zsh/mathfunc
(نیازمند zmodload
zsh/mathfunc)
$ 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) )) 3.1415926535897931 $ echo $(( f = sin(0.3) )) 0.29552020666133955 $ print $((1e12 * rand48())) 847909677310.23413 $ print $(( rand48(seed) )) 0.01043488334700271
zsh/termcap
(نیازمند zmodload
zsh/termcap)
$ zmodload -ab zsh/termcap echotc
$ GREEN=`echotc AF 2`
$ YELLOW=`echotc AF 3`
$ RED=`echotc AF 1`
$ BRIGHTRED=`echotc md ; echotc AF 1`
$ print -l ${GREEN}green ${YELLOW}yellow ${RED}red ${BRIGHTRED}brightred
zsh/zpty
(نیازمند zmodload
zsh/zpty)
$ zmodload zsh/zpty $ zpty PW passwd $1 $ zpty PW passwd $1 # ``-r'': خواندن خروجی نام دستور. # ``z'' : پارامتر $ zpty -r PW z '*password:' # ارسال رشتههای ارائهشده به عنوان ورودی به نام دستور $ zpty -w PW $2 $ zpty -r PW z '*password:' $ zpty -w PW $2 # شکل دوم، با گزینه -d، برای حذف دستورهایی به کار میرود که # پیشتر آغاز شدهاند، از طریق ارائه فهرستی از نامهای آنها. اگر هیچ نامی # داده نشود، تمام دستورها حذف میشوند. حذف یک دستور باعث ارسال # سیگنال HUP به فرایند متناظر میشود. $ zpty -d PW
zsh/net/socket
(نیازمند zmodload
zsh/net/socket)
# ``-l'': باز کردن یک سوکت شنونده روی نام پرونده # ``-d'': آرگومان به عنوان توصیفگر پرونده هدف برای اتصال # در نظر گرفته میشود # ``3'' : توصیفگر پرونده. به ``A User's Guide to the Z-Shell'' رجوع کنید # (3.7.2: File descriptors) $ zmodload zsh/net/socket $ zsocket -l -d 3 # ``-a'': پذیرش یک اتصال ورودی به سوکت $ zsocket -a -d 4 3 $ zsocket -a -d 5 3 # پذیرش یک اتصال $ echo foobar >&4 $ echo barfoo >&5 $ 4>&- 5>&- 3>&
zsh/zftp
(نیازمند zmodload
zsh/zftp)
$ autoload -U zfinit
$ zfinit
$ zfparams www.example.invalid myuserid mypassword
$ zfopen
$ zfcd tips
$ zfls -l zshtips.html
$ zfput zshtips.html
$ zfls -l zshtips.html
# انتقال خودکار پروندهها با استفاده از FTP به همراه بررسی خطا
$ autoload -U zfinit ; zfinit
$ zftp open host.name.invalid user passwd || exit
$ zftp get /remote/file > /local/file; r=$?
$ zftp close && exit r
# فشردهسازی و ارسال با ftp به طور همزمان
$ autoload -U zfinit ; zfinit
$ zftp open host.name.invalid user password
$ zftp get $file | bzip2 > ${file}.bz2
$ zftp close
# دریافت (``get'') بازگشتی
$ autoload -U zfinit ; zfinit
$ zfanon cr.yp.to
$ zfcd daemontools
$ for file in `zfls` ; do
> zfget $file
$ done
$ zfclose
# بارگذاری تمام پروندههای عادی در $HOME/foobar (بازگشتی) که جدیدتر از
# دو ساعت هستند به 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
# فهرست کامل پروندهها در یک سرور ftp
$ autoload -U zfinit ; zfinit
$ zfopen some-host
$ zfcd /some/remote/Dir
$ cd /some/local/Dir
# اگر list.txt روی میزبان راه دور قرار دارد، به این تغییر دهید:
# zfget ${(f)"$(zftp get /path/to/remote/list.txt)"}
$ zfget ${(f)"$(cat list.txt)"}
$ zfclose
zsh/zselect
(نیازمند zmodload
zsh/zselect)
# این مشابه است با ,---- | $ sg=$(stty -g) | $ stty -icanon min 0 time 50 | $ read yesno | $ stty "$sg" | $ case "$yesno" in | > yes) command1;; | > *) command2;; | > esac `---- $ zmodload zsh/zselect $ if zselect -t 500 -r 0 && read yesno && [ yes = "$yesno" ]; then > command1 > else > command1 > fi
گزینههای پیمایش (Navigation options)
auto_cd (امکان رفتن به یک دایرکتوری تنها با وارد کردن نام آن به عنوان دستور). auto_pushd (افزودن خودکار دایرکتوریها به فهرست push/pop) pushd_ignore_dups (و جلوگیری از تکراری شدن آنها در فهرست).
متفرقه (Misc)
no_hup (عدم ارسال سیگنال HUP به کارهای پسزمینه هنگام خروج از ZSH). print_exit_value (نمایش پیامی حاوی کد خروج هنگامی که دستوری با کد خروجی غیرصفر به پایان میرسد)
گزینههای
تاریخچه (History
options)
hist_verify (امکان ویرایش خط فرمان توسط کاربر پس از بسط تاریخچه (مانند !ls) به جای اجرای فوری آن) استفاده از یک فایل تاریخچه یکسان برای همه نشستها: setopt SHARE_HISTORY
حریم
خصوصی /
امنیت (Privacy / Security)
no_clobber (یا set -C؛ جلوگیری از بازنویسی و خالی شدن فایل با بازهدایت > در صورتی که فایل از قبل وجود داشته باشد)
تصحیح
املا (Spelling correction)
correct (تصحیح خودکار املای دستورها). correct_all (تصحیح خودکار املای تمام واژهها در خط فرمان) dvorak (طرحبندی صفحهکلید dvorak)
مرتبنشده/متفرقه (UNSORTED/MISC)
Mailpath: چند mailpath ساده:
mailpath=($HOME/Mail/mbox'?new mail in mbox'
$HOME/Mail/tux.u-strasbg'?new mail in tux'
$HOME/Mail/lilo'?new mail in lilo'
$HOME/Mail/ldap-fr'?new mail in ldap-fr')
Mailpath: مسیر ایمیل (mailpath) پویا:
typeset -a mailpath
for i in ~/Mail/Lists/*(.); do
mailpath[$#mailpath+1]="${i}?You have new mail in ${i:t}."
done
جلوگیری از بسط الگو (globbing) در دستورهای خاص:
for com in alias expr find mattrib mcopy mdir mdel which; alias $com="noglob $com"
برای انتقال bashprompt خود به zsh از اسکریپت bash2zshprompt واقع در توزیع منبع zsh در شاخه Misc استفاده کنید.
برای مهاجرت از (t)csh به zsh از ابزار c2z استفاده کنید که نامهای مستعار (aliases)، متغیرهای محیطی و متغیرهای پوسته csh را به zsh تبدیل میکند. این کار با اجرای csh و گزارشگیری csh از نامهای مستعار و متغیرها انجام میشود. سپس اسکریپت این موارد را به فایلهای راهاندازی zsh تبدیل میکند. این اسکریپت دارای نکاتی پیرامون مسائل احتمالی و اطلاعات استفاده است که در بالای آن مستند شدهاند.
در اینجا توابعی برای تنظیم عنوان (title) و وضعیت سختافزاری (hardstatus) در یک XTerm یا GNU Screen ارائه شده است؛ هنگام نمایش اعلان (prompt)، عنوان و وضعیت سختافزاری به ترتیب روی zsh و دایرکتوری جاری، و هنگام اجرای دستور، به ترتیب روی نام دستور و بقیه خط فرمان تنظیم میشوند:
function title {
if [[ $TERM == "screen" ]]; then
# Use these two for GNU Screen:
print -nR $' 33k'$1$' 33'\
print -nR $' 33]0;'$2$''
elif [[ $TERM == "xterm" || $TERM == "rxvt" ]]; then
# Use this one instead for XTerms:
print -nR $' 33]0;'$*$''
fi
}
function precmd { title zsh "$PWD" }
function preexec {
emulate -L zsh
local -a cmd; cmd=(${(z)1})
title $cmd[1]:t "$cmd[2,-1]"
}
خط زیر را در ~/.screenrc خود قرار دهید تا این hardstatus زیبا را مشاهده کنید:
caption always "%3n %t%? (%u)%?%?: %h%?"
متغیرهای ویژهای که مقداردهی میشوند:
$LINENO $RANDOM $SECONDS $COLUMNS $HISTCHARS $UID $EUID $GID $EGID $USERNAME $fignore $mailpath $cdpath
وبگاه اصلی
صفحات وب Zsh
صفحه پروژه
کتاب From Bash to Z Shell: Conquering the Command Line
«Zsh - die magische Shell» (کتابی آلمانی درباره Zsh) اثر Sven Guckes و Julius Plenz
بایگانی فهرستهای پستی
پرسشهای متداول (ZSH-FAQ)
راهنمای کاربر
ویکی ZSH (پیوند بایگانیشده)
پشتیبانی از ماوس ;)
مقدمهای بر اعلان ZSH
پستهای وبلاگ ft درباره zsh
پیکربندی zsh متعلق به ft
صفحه ZSH متعلق به Adam
بهترین ترفندهای ZSH از Zzapper (پیوند بایگانیشده)
صفحه وب Zsh توسط Christian Schneider
صفحه وب zsh-lovers
کانال IRC
برگه مرجع Z shell (گنجاندهشده در بسته دبیان zsh-lovers)
نویسندگان (AUTHORS)
این صفحه راهنما توسط Michael Prokop، Christian strcat Schneider و Matthias Kopfermann نوشته شده است. اما ایدههای بسیاری از خورههای zsh، از جمله از فهرستهای پستی zsh (مانند zsh-users و zsh-workers)، گوگل، گروههای خبری و zsh-Wiki گرفته شده است. با سپاس از نکات جالب و فوقالعاده شما. ما چیزهای زیادی از شما آموختیم!
به ترتیب الفبا:
Andrew 'zefram' Main - http://www.fysh.org/~zefram Barton E. Schaefer - http://www.well.com/user/barts 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:
zsh نمای کلی Zsh zshall فراراهنمای پوستهٔ Z zshbuiltins دستورهای توکار Zsh zshcalsys سامانه گاهشمار zsh zshcompctl تکمیل خودکار برنامهپذیر zsh zshcompsys سامانه تکمیل خودکار Zsh zshcompwid ابزارکهای تکمیل خودکار Zsh zshcontrib مشارکتهای کاربران در zsh zshexpn بسط و جایگزینی در Zsh zshmisc هر آنچه در سایر بخشها نمیگنجد zshmodules پیمانههای بارگذاریپذیر Zsh zshoptions گزینههای Zsh zshparam پارامترهای Zsh zshroadmap معرفی غیررسمی راهنمای zsh zshtcpsys سامانه tcp در Zsh zshzle ویرایش خط فرمان Zsh zshzftpsys کارخواه توکار FTP در Zsh zshall فراراهنمای شامل تمام موارد بالا
نکته: بهویژه man zshcontrib موضوعات بسیار مفیدی را پوشش میدهد! کتاب: From Bash to Z Shell نوشتهٔ Oliver Kiddle، Jerry Peck و Peter Stephenson. ISBN: 1590593766. - bash2zsh.com همچنین نگاهی به بخش LINKS در این صفحهٔ راهنما بیندازید.
گزارش باگها (BUGS)
احتمالاً. این صفحهٔ راهنما ممکن است هرگز کامل نباشد. بنابراین لطفاً باگها، بازخوردها و پیشنهادها را از طریق https://github.com/grml/zsh-lovers گزارش دهید. با تشکر!
کپیرایت و تکثیر (COPYRIGHT)
کپیرایت (C) متعلق به Michael Prokop، Christian Schneider و Matthias Kopfermann است.
| 12/04/2024 |