web-dev-qa-db-ja.com

履歴から連続したコマンドを実行するには?

以前に実行した4つのコマンドのシーケンスを実行するとします。コマンド履歴で最初のものが432の場合、次のようにできます。

$ !432; !433; !434; !435

私は興味があります、これを達成するためのより効率的な方法はありますか?

50
Eric Wilson

最近実行されたコマンドを参照する場合、より効率的な方法は、負の数でそれらを参照することです。

!-4; !-3; !-2; !-1

また、一度実行すると、最後の履歴エントリにはコマンドのチェーン全体が含まれるため、!!で繰り返すことができます。


編集:まだの場合は、優れた組み込み関数fcに慣れてください。 Gillesが言及。 (help fcを使用してください。)負の数を使用することもできるので、上記と同じように使用できます。

eval "`fc -ln -4 -1`"

ただし、注意点が1つあります。この後、eval行が最後のコマンドとして履歴に保存されます。したがって、これをもう一度実行すると、ループに陥ります。

これを行うためのより安全な方法は、デフォルトのfc操作モードを使用することです。選択した範囲のコマンドをエディターに転送し、終了するとコマンドを実行します。試してください:

 fc -4 -1

コマンドの範囲の順序を逆にすることもできます:fc -1 -4

49
rozcietrzewiacz

履歴内のコマンドの範囲を表示するには、組み込みの fc コマンドを使用します。

fc -ln 432 435

それらを再度実行するには:

eval "$(fc -ln 432 435)"

Bashの履歴からいくつかのコマンドを順番に実行するための素晴らしい代替方法があります。
履歴の代用を使用する代わりに(!432または!-4)を使用して、履歴を検索できます Ctrl+r、そして実行したい最初のコマンドを見つけたら、 Ctrl+o (次の操作と取得)の代わりに return キー
これにより、履歴からコマンドを起動して次のコマンドを提案しますになります。あなたは打つことができます Ctrl+o 好きなだけ何度でも、シーケンスを終了して return 最後のもの、または Ctrl+c 起動せずに停止します。

10

コマンドを編集するのではなく、すぐに実行するために、構文的にスリムなバージョンの Giles answer using eval を次に示します。

fc -e: 432 435

-eのコロン引数はbash noopであり、fcが必要とする「エディターで開く」ステップをスキップする効果があります。また、(最近の)履歴には、evalステートメントではなく、履歴からの実際のコマンドが含まれます。

8
user1543542

fc forループおよびxsel

これは、最後のn個のコマンドを複数回連結して再実行する場合にうまく機能します。

fcn() (
  from="${1:-2}"
  to="${2:-1}"
  if [ "$from" -ne "$to" ]; then
    for i in `seq "$from" -1 "$(($to + 1))"`; do
      printf "$(fc -ln -${i} -${i}) && "
    done
  fi
  printf "$(fc -ln -${to} -${to})"
)

次に:

$ echo a
a
$ echo b
b
$ echo c
c
$ fcn 3 1 | xsel -b
$ # Paste.
$  echo a &&  echo b &&  echo c
a
b
c
$ # Paste again if you feel like it.
$  echo a &&  echo b &&  echo c
a
b
c

または、編集が必要になる可能性のある大きなコマンドの場合:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh