!*のBash履歴キーボードショートカット


8

Bashには、最後のコマンドの一部を繰り返す便利な演算子がいくつかあります。

  • !^ 前のコマンドの最初の引数に展開します。たとえば、

    $ echo one "two three"
    one two three
    $ echo !^
    echo one
    one
  • !$ 前のコマンドの最後の引数に展開します。たとえば、

    $ echo one "two three"
    one two three
    $ echo !$
    echo "two three"
    two three
  • !* 前のコマンドのすべての引数に展開します。たとえば、

    $ echo one "two three"
    one two three
    $ echo !*
    echo one "two three"
    one two three

(私が理解している限り、これらはそれぞれ!!:^!!:$およびの構文シュガーであり、は前のコマンドに拡張されるイベント指定子、およびは単語指定子です。Bashリファレンスマニュアルまたはを参照してください。)!!:*!!^$*man bash

これらはしばしば非常に便利です。しかし、キーボードショートカットを使用するとさらにクールになります。

  • あなたがヒットするとAlt+ .またはAlt+を_、前のコマンドの最後の引数は、あなたが書かれていたかのように同様に、現在のコマンドに挿入された!$その時点で。

  • Alt+ + Ctrl+ yを押して!^、その時点で書き込んだかのように、前のコマンドの最初の引数を挿入することもできます。

GNU Readline Libraryまたはを参照してくださいinfo readline。)

コマンドを実際に実行する前に挿入する内容を確認できるため、Bashの履歴演算子よりもキーボードショートカットを好む傾向があります。ただし、前のコマンドのすべての単語を挿入できるショートカットがないようです。つまり、!*の仕事です。少なくとも私はそれを見つけることができませんでした。

そのようなショートカットはありますか?そうでない場合、それを追加するようにreadlineライブラリを構成することは可能ですか?


AFAIK、キーボードショートカットは端末エミュレータによって処理されます。だから私はあなたがgnome-terminalを使っていると思いますか?
Seth

1
ではzsh、タイプecho !*してからTabキーを押すと、目的の効果が得られます。一般に、TABはreadlineにある間、すべてのエキスパンドを展開します。とても便利な; おそらくbashは同じ効果を持ついくつかの設定を持っていますか?@Seth、これはターミナルエミュレーターではなく、bashへのreadlineだと思います。
ルマノ2014年

2
@Sethいいえ、Qからのショートカットはbashによって処理されます。あなたは、のためにSERCHできるの歴史を操作するためのコマンド"man bash(ライン3030でどこか)
ラドゥRădeanu

@RaduRădeanuおもしろい!知らなかった。悪い仮定のための私の悪い。
Seth

1
\e.そして、\e_readlineの関数にマップされているyank-last-arg\e\C-yにマッピングされていますyank-nth-arg。残念なことに、以前の引数を一度に複数追加する(単一の)コマンドはないようです。
Adaephon 2014年

回答:


5

次のコマンドの出力を確認すると、

bind -l

またはより良い:

bind -l | grep arg

たとえば、yank-last-arg最後の引数のように、すべての引数に対してreadline関数が存在しないことがわかります。これは、前のコマンド(前の履歴エントリの最後の単語)に最後の引数を挿入できます。そのため、そのような関数が存在しない場合は、たいていの場合、望みを達成するためのショートカットが存在しません。

あなたのリクエストに近づいたものをクレートしてみましょう...

まず、次のコマンドの出力例を見てください。

bind -p | grep yank-nth-arg

出力は次のとおりです。

"\e\C-y": yank-nth-arg

次のように変換できますyank-nth-arg(これは、前のコマンドに最初の引数を挿入します-引数nを使用して、前のコマンドからn番目の引数を挿入します)はAlt+ Ctrl+にバインドされyます。

同様に、bind -pコマンドの出力から任意の行を解釈できます。

次のシナリオで注目してください。

  • 次のバインディングを設定した場合:

    bind '"\ea": "\e2\e."'

    Alt+ Aは、前のコマンドの2番目の引数を挿入するためにマップされるAlt+ 2Alt+ .にマップされます。だから、あなたは押したときの後にAlt+をA第二直前のコマンドの引数には、現在のコマンドに挿入されています。

  • 設定した場合:

    bind '"\ea": "\e1\e. \e2\e."'

    あなたが押したときに後Alt+をA最初の二つ前のコマンドの引数は、現在のコマンドに挿入されています。もちろん、前のコマンドからの引数の数が最大2の場合、前のコマンドのすべてが現在のコマンドに挿入されます。

  • 設定した場合:

    bind '"\ea": "\e1\e. \e2\e. \e3\e."'

    あなたが押したときに後Alt+をA最初の3つの前のコマンドの引数は、現在のコマンドに挿入されています。前のコマンドの引数の数が最大3の場合(あなたの場合と同様)、もちろん、前のコマンドのすべてが現在のコマンドに挿入されます。

  • 等々。

最初の10個の引数には、次のものを使用できます。

bind '"\ea": "\e1\e. \e2\e. \e3\e. \e4\e. \e5\e. \e6\e. \e7\e. \e8\e. \e9\e. \e1\e0\e."'

そして、私はあまりにも多くの引数を持つコマンドをあまり使用しない限り、これは十分に長いと思います。

永続化するには、次の行を~/.inputrcファイルに追加します。

"\ea": "\e1\e. \e2\e. \e3\e. \e4\e. \e5\e. \e6\e. \e7\e. \e8\e. \e9\e. \e1\e0\e."

この例では、前のコマンドのすべての引数(引数の数が10以下の場合)を挿入するためにAlt+ を選択Aしましたが、前のコマンドで\ea文字列を置き換えることにより、他の任意の組み合わせを選択できます。

リソース:


まあ、それはややハックであり、限られた数の引数に対してのみ機能しますが、それは私たちが簡単に取得できる最も近いようです-私はそれをとります;)実際、私はreadlineのソースコードを見ただけです。一見すると、ファイルのように見えますfunmap.cが、関数yank-nth-argはC関数にマップされ、C関数rl_yank_nth_argはで定義されていkill.cます。同様にyank-last-arg。もちろん、そのような機能でreadlineを拡張することは可能ですが、私はそうしたくありません。私は私のreadlineがで管理することを好むapt、この機能ではないことが重要;)
マルタSkoruppa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.