私はzshを使い始めたばかりです(昨日bashから移行しました)
私はbashで次のようなbash関数を持っていました
vl() { cmd=`echo $1 | sed -r 's/(.+):([0-9]+).+/\1 +\2/g'`; vim $cmd }
これは基本的に次のような引数を変換します:
vl ./manifests/production/test.pp:387:foobar # A output of $grep -iHn test
に
vim ./manifests/production/test.pp +387 #Aim is to open file at line-number 387
zsh の同じ関数は期待どおりに動作しません。 が追加された名前のファイルを開くのではなく、vim で名前が付けられたファイルを開きます。./manifests/production/test.pp +387
に引用符を追加しているようです。./manifests/production/test.pp
+387
$cmd
ここで何が起こっているのか誰か説明してくれると嬉しいです。ありがとう
答え1
Bourne シェル、dash、ksh、bash などの通常の Bourne スタイルのシェルでは、構文は$variable
「変数の値を取得し、文字がIFS
出現する個別の単語に分割し、各単語をファイル名のワイルドカード パターンとして扱い、1 つ以上のファイルに一致する場合は拡張する」ことを意味します。がvariable
配列の場合、これは配列の最初の要素に対して行われ、他の要素は無視されます。
zsh では、構文は$variable
「変数の値を取得するが、空の場合は削除する」という意味です。variable
配列の場合は、配列のすべての要素に対してこれが行われます。zsh 愛好家は、zsh の方法が優れていると考えています。
$=variable
zsh では、単語分割を実行するように記述できます。ただし、これは、実行しようとしていることを実行する最善の方法ではありません。bash 関数はファイル名の空白文字に対応しておらず、 $=variable
zsh での使用も同様です。次に、bash と zsh の両方で機能し、:
ファイル名以外の任意の文字に対応する、引数を解析する別の方法を示します。引数に 2 つのコロンが含まれている場合、最初のコロンの後のすべてが削除され、最初のコロンと 2 番目のコロンの間の部分が、先頭に符号が付いた別の引数として追加されます+
。これは、コードより少し長くなりますが、理解しにくくはなく、ファイル名にスペースが少しでも含まれていても詰まることはありません。
vl () {
local suffix
case $1 in
*:*:*) suffix=${1#*:};; set -- "${1%%:*}" "+${suffix%%:*}";;
esac
vim "$@"
}
答え2
これは難しい問題です :) 回避策の 1 つは、次のように関数を定義することです。
vl() { cmd=$(echo $1 | sed -r 's/(.+):([0-9]+).+/\1 +\2/g'); eval "vim $cmd"; }
回避策は を使用することでありeval
、必要な StackExchange 編集スキルがないために行ったその他の小さな変更ではないことに注意してください 8-)