内容
1. READNULLCMDを使用する
READNULLCMD変数は、コマンドを入力せずにstdinリダイレクトが使用される場合に呼び出されるコマンドを定義します:
<file.txt
。 この方法では、はるかに少ない文字を入力することで
less
を呼び出すことができます。単に
READNULLCMD=less
設定して
READNULLCMD=less
。
2.開閉ブラケットを挿入します
Vimのようなエディターでは、アドオンが入力されたときに自動的に括弧を閉じるためによく使用されます。 つまり
[
を入力すると、中央にカーソルを置いて
[]
を取得します。 シェルでは、これも可能です(bashでも):
binkey -s "[" $'\Cv[]\C-b'
ようなものを使用する必要があります。このコマンドに相当するものは.inputrcに配置することもできます。 zshのより普遍的なソリューションには、ZLEウィジェットの使用が含まれます。
insert-double-brackets() { LBUFFER="${LBUFFER}[[ " RBUFFER=" ]]${RBUFFER}" } zle -N insert-double-brackets bindkey ',H' insert-double-brackets
ここで、LBUFFER変数にはカーソルの前のコマンドライン全体が含まれ、RBUFFER変数には後の全体が含まれます。 2番目のコマンドはウィジェットを作成し、3番目はウィジェットを組み合わせ,H
割り当てます。したがって、input
,H
はカーソルが中央にある
[[ ]]
変わります。
3.グローバルエイリアス
おそらく、シェルでエイリアスが何であるかを知っているでしょうし、おそらく
alias hp='hg push'
ようなものを使用したでしょう。 zshのエイリアスには2つの追加機能があります:いわゆる サフィックスエイリアス。プログラムを入力せずにファイルを自動的に開くことができます(例:
alias -s txt=vim
は
foo.txt
を
vim foo.txt
変換します)。 私は前者を使用したことがなく、後者は非常に便利だと感じました。
グローバルエイリアスは、独立した単語を独自の意味に置き換えるために使用されます。 接尾辞や通常のエイリアスとは異なり、置換された単語はコマンドの位置にある必要はありません(つまり、コマンドラインの最初の単語、またはコマンドセパレータの後の最初の単語)。 エイリアスはメインパーサーが機能する前に処理されるため、グローバルエイリアスには、リダイレクト、
if
、コマンドセパレーターなど、すべてを含めることができます。
私の観点からは、さまざまなタイプのリダイレクトが最も便利です。
alias -g NN='&>/dev/null' alias -g L='|less' alias -g G='|grep'
この例では、3つのエイリアスが定義されています。1つはコマンドについてサイレントで、もう1つはlessを使用してコマンドの出力を表示し、3つ目は入力をフィルターします。 使用例: hg cat -r default file.csv G 42 L
書くの
hg cat -r default file.csv G 42 L
、
hg cat -r default file.csv | grep 42 | less
hg cat -r default file.csv G 42 L
同等
hg cat -r default file.csv | grep 42 | less
hg cat -r default file.csv | grep 42 | less
hg cat -r default file.csv | grep 42 | less
が、はるかに短い。
G
コマンドを入力に送信するには、エスケープを使用する必要があります:
\G
または
'G'
。
\G
と
'G'
も単語を形成し、それらに
alias -g "'G'=|grep"
が存在する可能性があることに注意してください:
alias -g "'G'=|grep"
、これを使用しないように気をつけてください事実。
その便利さにもかかわらず、zshのいくつかの機能により、グローバルエイリアスはzshアドオンを台無しにする可能性があるため、非常に危険です。 ある例では、
L)
という形式の条件もあるスクリプトを見ましたが、まったく異なる条件への変換のために機能しませんでした。 したがって、グローバルエイリアスは、すべてのアドオンを既にダウンロードした後、最新のものによって決定される必要があります。 定義後にアドオンをダウンロードするには、
ALIASES
設定を無効に
ALIASES
ます。次のようなものを使用します
source() { setopt localoptions setopt noaliases builtin source "${@[@]}" } .() { setopt localoptions setopt noaliases builtin . "${@[@]}" }
したがって、アドオンをダウンロードするための各オプションについては( source
と
.
に加えて、少なくともそのような機能の有効性については
autoload
があります。 ただし、グローバルエイリアスは対話型セッションでのみ危険であり、
#!/bin/zsh
を使用したスクリプトは影響を受けません。
4.端末設定を返す
cat /bin/test
(より正確には
cat any-binary-file
)を作成すると、さまざまな奇妙な効果が得られることは誰にとっても秘密ではありません。たとえば、入力した文字の一部をグラフィックス描画用の文字に置き換えます。 ほとんどの効果は盲目的に
echo $'\ec'
書くことで除去されますが、これは自動化したいものです。 フック
precmd
はこれに役立ち、シェルが表示される直前に関数を実行できます。 ターミナルに誤ってバイナリファイルを出力したり、エディター(Vim)がクラッシュしたり、ワインを起動した場合に何らかの問題が発生する(何らかの理由で入力モード(キーボード送信モード)が切り替わり、返されない):グラフィック文字通常、代替画面がメイン画面になり(=スクロールバック(入力履歴)はありません)、矢印が正常に機能しなくなり(キーボード送信がここにマークされました)、カーソルは表示されません。 それらを解決するために、次の関数が作成されました。
_echoti() { emulate -L zsh (( ${+terminfo[$1]} )) && echoti $1 } term_reset() { emulate -L zsh [[ -n $TTY ]] && (( $+terminfo )) && { _echoti rmacs # _echoti sgr0 # _echoti cnorm # _echoti smkx # «keyboard transmit mode» echo -n $'\e[?47l' # alternate screen # See https://github.com/fish-shell/fish-shell/issues/2139 for smkx } } zmodload zsh/terminfo && precmd_functions+=( term_reset ) ttyctl -f
。 導入後、 echo $'\ec'
と入力する必要はほとんどありません。
ttyctl -f
にも注意してください。この組み込みのzsh機能は、端末設定への変更をブロックします。特別なシーケンス(エスケープシーケンス)を使用して設定できる設定ではなく、
stty
を使用して設定されます。
5. zmv関数
複数のファイルの名前を自動的に変更するために、renameコマンドに遭遇した可能性があります。 perlで記述され、 Cで記述されたバリアントの 2つのコピーにも存在します。 Zshには似たような機能がありますが、より強力です。まず、この方法でファイルをコピーするか、単に
mv
ように動き回る代わりに
hg mv
を実行できます。 第二に、
noglob zmv -W *.c *.cpp
ような「直感的な」オプションを使用できます(
noglob
を取り除くには、
alias
使用します;さらなる例で
noglob
、
noglob
暗示されます)。 Zmvは正規表現を使用しませんが、globタスクにより適した表現を使用します。 2番目の引数として事実上任意の式を使用することもできます:
zmv -w test_*.c 'test/${1/_foo/_bar}'
は
test_foo_1.c
を
test_bar_1.c
ます。 ここで、形式
$N
パラメーターは、正規表現から「キャプチャーグループ」の類似物へのアクセスを提供し、
-w
は
test_*.c
を
test_(*).c
変換し
test_(*).c
すべての引数:
-
-f
:ターゲットファイルを無視します。 つまりtest.cpp
ファイルが存在する場合、zmv -W *.c *.cpp
コマンドは、ファイル間にtest.c
がある場合、ファイルの移動を拒否します。-f
は、zmvにこれを強制しますが、-f
引数をmv
渡しません。 -
-i
:各移動の前に必要性を明確にします。 肯定的な答えを得るには、y
またはY
を押す必要があります。失敗した場合は、他の何かを押す必要があります。 注意:y
またはY
のみを押してくださいY
Enterキーを押す必要はありません。次のファイルの失敗として認識されます。 -
-n
:zmvが実際に実行せずに実行するすべてのコマンドを出力します。 -
-Q
:glob修飾子を有効にします。 glob修飾子はキャプチャグループと混同しやすいため、デフォルトでは無効になっています。 グロブ修飾子は、結果を明確にするグロブの一部です。ソート順序を決定する修飾子、1つのグロブの設定を有効にする修飾子、および「シンボリックリンクのみを開く」などのこれらの状況で最も有用なフィルターがあります。 -
-s
:-s
オプション引数をコマンドに-s
ます。-L
またはzmv
ではなくzmv
同等の使用と組み合わせて使用します。 -
-v
:実行可能なコマンドを実行時に出力します。 -
-o
arg :コマンドに追加の引数を指定します。 したがって、zmv -o--fore
引数をmv
に渡すには、zmv -o--fore
を使用する必要があります。 一度だけ使用できます。 -
-p
prog :mvの代わりにこのプログラムを使用します。 チームは理解する必要があります:prog -- source target
として実行されます。 -
-P
prog :前の引数に似ていますが、理解できないコマンド用です--
。 プログラムはprog source target
として呼び出されます。 -
-w
:上記のように、すべてのワイルドカードのキャプチャグループを自動的に追加します。 -
-W
:前の引数と同じですが、グループをキャプチャするために作成された$N
パラメーターは、正しい引数のワイルドカードに自動的に使用されます。 -
-C
、-L
、および-M
:-pcp
、-pln
、および-pmv
それぞれ似ています:関数名に関係なく、コピー、シンボリックリンクの作成、または移動を使用できます(デフォルトでは、zmvと同じコードを使用する2つの追加関数があります:zcpおよびzln)。
6.字幕を自動的に見つけてmpvを開始
トレントから外部字幕付きのテレビ番組をダウンロードしたことがある場合、それらをアップロードする各人が字幕の場所について自分の意見を持っていることに間違いなく気付くでしょう。 主なオプションは2つあります。自分のディレクトリとビデオのすぐ隣にありますが、「独自のディレクトリ」の下では、ディレクトリの名前はすべて隠すことができます。また、さまざまな深さの添付ファイルもあります。「subs {sub group}」、「subtitles {sub group}」 、「Subs / {sub group}」、さらには「{sub group}」です。 追加の問題は、字幕とともに非標準のフォントを使用し、字幕とともに配布することです。
字幕を選択して正しいフォントを使用するには、さまざまな方法を使用できます。 ほとんどすべての場合に適切なジョブを自動的に実行する関数を作成することを好みました。
aplayer() { emulate -L zsh setopt extendedglob setopt nullglob local -a args args=() local -A mediadirs mediadirs=() for arg in $@ ; do if [[ ${arg[0]} == '-' ]] ; then continue fi if test -f $arg ; then mediadirs[${arg:A:h}]=1 fi done local d local -i found=0 for d in ${(k)mediadirs} ; do local tail=$d:t test -d ~/.fonts/aplayer/${tail}-1 && continue local f for f in $d/**/(#i)font* ; do if test -d $f ; then (( found++ )) ln -s $f ~/.fonts/aplayer/${tail}-${found} elif [[ $f == (#i)*.rar ]] || [[ $f == (#i)*.zip ]] ; then (( found++ )) mkdir ~/.fonts/aplayer/${tail}-${found} pushd -q ~/.fonts/aplayer/${tail}-${found} 7z x $f popd -q fi done done if (( found )) ; then fc-cache -v ~/.fonts fi local -aT subpaths SUBPATHS local -A SUBPATHS_MAP SUBPATHS=( ${(k)^mediadirs}/(#i)*(sub|)*{,/**/*}(/) ) for sp in $SUBPATHS ; do SUBPATHS_MAP[$sp]=1 done local -a subarr for d in ${(k)mediadirs} ; do for subd in $d/**/ ; do if ! test -z $SUBPATHS_MAP[$d] ; then continue fi subarr=( $subd/*.(ass|ssa|srt) ) if (( $#subarr )) ; then SUBPATHS_MAP[$subd]=1 SUBPATHS+=( $subd ) fi done done if (( ${#SUBPATHS} )) ; then args+=( --sub-paths $subpaths ) fi mpv $args $@ &>/dev/tty }
zshに連想配列のようなものがあることは、そのような関数を作成するときに非常に役立ちます。
ここで、関数の最初の部分はすべての引数を調べて、mediadirsの連想配列にある作品のディレクトリを詰まらせます。 重複を避けるためだけに結合されます。
次に、この機能は、作品を含むすべてのカタログを調べて、それらのフォントまたはアーカイブ内またはサブディレクトリ内にあるサブディレクトリ内のフォントを検索します。 フォントは特性名(名前の先頭にある
font
の存在)によって識別されます
setopt nullglob
使用すると、
font
が存在しないことを心配する必要がありません(デフォルトでは、存在しないとエラーが発生します)。
setopt extendedglob
と
(#i)
組み合わせて使用すると、
setopt extendedglob
を
setopt extendedglob
せずに済みます。
(#i)
フォントを
FONTS
ディレクトリと
Fonts
両方に配置できます。
~/.fonts
フォントを見つけてインストールした後
~/.fonts
インデックスは
fc-cache
を使用して更新されます。それ以外の場合、正しいディレクトリにコピーされたフォントも使用されません。
${(k)ASSOCIATIVE_ARRAY}
は、連想配列をキーの単純な配列に変換します。
3番目のサイクルでは、字幕付きのディレクトリが検出され、「subs」や「subtitles」などの「単純な」名前を持つ連想配列にたたき込まれます。 繰り返しますが、大文字と小文字を区別せず、最後に個別に
(/)
を使用して、globをディレクトリのみに制限します(glob修飾子の例)。
${^array}
使用して、
array=( abc ); echo ${^array}*
array=( abc ); echo ${^array}*
は
echo {a,b,c}*
と同等でした。
最後のサイクルでは、非標準の方法と呼ばれる字幕付きのディレクトリを見つけます。 字幕ディレクトリは、拡張子が
ass
、
srt
または
srt
ファイルを少なくとも1つ含む(ビデオのあるディレクトリに関連する)任意のサブディレクトリ
srt
。
かなり奇妙なコードがあることに注意してください:誰も
subpaths
変数に触れていないようですが、その値は引数
--sub-paths
として使用され
--sub-paths
。 実際、値の配列(通常はディレクトリ)が異なる値が区切り文字(通常はコロン)で区切られた単純な文字列である場合、zshはかなり頻繁にパターンを記録します
PATH
変数はそのような「配列」の例です。 ただし、プログラマは配列と同じようにこのような配列を操作するのが便利なので、変数の1つが配列(例:
path
)であり、指定された(デフォルトのコロン)セパレータ(例:
PATH
) 、一方の変数の変更が他方に自動的に反映されます。 これは、
SUBPATHS
配列が
subpaths
文字列に関連付けられた
subpaths
です。
7.引数の自動スクリーニングを使用したコマンドの作成
一部のコマンドの引数は決してファイルではありません。 ただし、この事実はzshがテンプレートを展開するのを止めません。 通常の場合、
alias mycmd='noglob mycmd'
を書くだけで、
mycmd *.foo
は
mycmd '*.foo'
と同等になります。 しかし、入力を文字通り
$VAR
に送信し、
'$VAR'
を書きたくないチームを作成する場合はどうでしょうか。 ここで、
zpy import zsh; print(zsh.getvalue("PATH"))
を記録するコードの例を
zpy import zsh; print(zsh.getvalue("PATH"))
zpy import zsh; print(zsh.getvalue("PATH"))
、
zpython 'import zsh; print(zsh.getvalue("PATH"))'
と同等
zpython 'import zsh; print(zsh.getvalue("PATH"))'
zpython 'import zsh; print(zsh.getvalue("PATH"))'
; もちろん、対話モードでのみ:
zshaddhistory() { emulate -L zsh if (( ${+_HISTLINE} && ${#_HISTLINE} )) ; then print -sr -- "${_HISTLINE}" unset _HISTLINE elif (( ${#1} )) ; then print -sr -- "${1%%$'\n'}" fi fc -p } accept-line() { emulate -L zsh if [[ ${BUFFER[1,4]} == "zpy " ]] ; then _HISTLINE=$BUFFER BUFFER="zpython ${(qqq)BUFFER[5,-1]}" fi zle .accept-line } zle -N accept-line
関数の主要部分:ウィジェットaccept-lineを呼び出すとき(Enterを押すと呼び出されます)、行がzpy
で始まるかどうかが判別され、そうであれば、行は
zpython …
に置き換えられ
zpython …
。ここで
…
は、
zpy
およびspaceの後の行のエスケープ部分です。
zshaddhistory
関数
zshaddhistory
使用して、ソース文字列
zshaddhistory
置換ではなく履歴に
zshaddhistory
されるようにします。
このようにして、任意のカスタム構文をzshに追加できます。
8.グローブからの自動ファイル除外
Vimエディターがあり、それを使用してディレクトリーからすべてのファイルを開くことを想像してください(
*
テンプレートを使用)。 しかし、ディレクトリ内の単純なテキストファイルに加えて、
*.o
(オブジェクト)ファイルのような多くのバイナリを開きます。 これを行うには、単なるアスタリスクの代わりに、必要なファイルに対応するいくつかのテンプレートを作成できます。 または、例外パターンを使用します(
*~*.o
、
setopt extendedglob
が必要
setopt extendedglob
)。 しかし、比較的簡単なトリックで、これは自動化できます:
filterglob () { local -r exclude_pat="$2" shift local -r cmd="$1" shift local -a args args=( "${@[@]}" ) local -a new_args local -i expandedglobs=0 local first_unexpanded_glob= for ((I=1; I<=$#args; I++ )) do if [[ $args[I] != ${${args[I]}/[*?]} ]] then local initial_arg=${args[I]} args[I]+="~$exclude_pat(N)" new_args=( $~args[I] ) if (( $#new_args )) ; then expandedglobs=1 else if [[ $options[cshnullglob] == off && $options[nullglob] == off ]] ; then if [[ $options[nomatch] == on ]] ; then : ${~${args[I]%\(N\)}} # Will error out. else new_args=( "$initial_arg" ) fi fi if [[ -z $first_unexpanded_glob ]] ; then first_unexpanded_glob=${args[I]%\(N\)} readonly first_unexpanded_glob fi fi args[I,I]=( "${new_args[@]}" ) (( I += $#new_args - 1 )) fi done if [[ $options[cshnullglob] == on && $options[nullglob] == off ]] ; then if (( !expandedglob )) ; then : $~first_unexpanded_glob # Will error out. fi fi "$cmd" "${args[@]}" } alias vim='noglob filterglob "*.o" vim'
これはエイリアスが定義されている場所で、zsh(noglob)がテンプレート自体を展開するのを防ぎますが、関数を使用してテンプレート自体(filterglob)を展開するvimを開きます。 しかし、それは単にそれらを開くだけでなく、 vim *
が
vim *~*.o
ように機能するようにパターン例外を付けてそれを完成させます。
この関数は、zshの次の機能を使用します。
${~var}
〜var
${~var}
は、zshに
var
変数の値に関してテンプレート展開を使用させ、変数自体の代わりにテンプレート展開の結果を置き換えます。
array[idx1,idx2]=( $new_array )
は、
idx1
から
idx2
までの配列の一部を削除し、削除された要素の代わりに
new_array
配列の値を挿入します。
array
のサイズは変更される場合があります。 次の形式の構造
: $~var
とコメント「Will error out」は、zshが期待されるエラーを表示するために必要です。 この場合、関数の実行は完了します。
echo … >&2
代わりにこのオプションを使用する特別な理由はありませんが、私の場合は
always
(インタラクティブセッションではほとんど使用しない)エラー
always
をサポートしているようです。