前のコマンドの最後のパラメータから2番目のパラメータのみを取得する

前のコマンドの最後のパラメータから2番目のパラメータのみを取得する
[ -f /root/.bash_aliases ] || echo "$_"

私にください]

私の考えでは/root/.bash_aliases

私も試しました

[ -f /root/.bash_aliases ] || echo !:2

しかし、それは私に次のような結果を与えます

[ -f /root/.bash_aliases ] || echo /root/.bash_aliases
/root/.bash_aliases

私はほしいだけです。/root/.bash_aliases

答え1

この機能の目的は次のとおりです。

print_if_not_regular() {
  [ -f "$1" ] || printf '%s\n' "$1"
}
print_if_not_regular /root/.bash_aliases

一部のシェルには匿名機能があるか、次の機能がありますeszsh

(){[ -f "$1" ] || printf '%s\n' $1} /root/.bash_aliases # zsh
@ {[ -f $1 ] || printf '%s\n' $1} /root/.bash_aliases # es

$_たとえば、DEBUGトラップがあると動作しなくなります。

$ bash -c 'trap ": \"\$((cmdcount+=1))\"" DEBUG; echo foo; echo "$_"'
foo
2

これは!:n最後のコマンドのn番目の引数ではなく、前のコマンドラインのn番目の語彙トークンです(記録の最後の行(および複数行)に格納されています)。例えば、

echo $(echo A B)
echo foo; echo !:1

(最後のコマンドの最後の引数)または(前のコマンドラインのコマンドの最後の引数)!:1に拡張されず、代わりに拡張されます。ここに次のように入力する必要があります。fooBechoecho$(echo A B)

[ -f /root/.bash_aliases ] ||
  echo !:2

つまり、別の行に入力します。ここでは、2行目を入力したときに履歴行が完全に終了していなくても(偶然に)機能します。同じトリックが(t)csh(歴史的拡張のソース)では機能しませんzsh

答え2

使用

test -f /root/.bash_aliases || echo "$_"

または

test -f /root/.bash_aliases || printf '%s\n' "$_"

$_前のコマンドの最後の引数に展開されます。あなたの例では、前のコマンドはであり、[最後の引数はです]

上記の最後のコマンドは、test最後のパラメータがファイル名であることです。

test[同じコマンドですが、最後のコマンドライン引数として[aが必要です。]この場合、$_ファイル名を取得するのに使用するのが難しい理由です。

上記のソリューションには、少なくともbashDEBUGトラップを設定しない限り)で作業できるという利点がありますzsh


ファイル名が変数にある場合は簡単です。

[ -f "$name" ] || printf '%s\n' "$name"

または

if [ ! -f "$name" ]; then
    printf '%s\n' "$name"
fi

ifステートメントと段落論理テストの好みによって異なります。

関連情報