ループを書くのではなく、最後のコマンドをN回繰り返す方法はありますか?.
たとえば、ダブルバン(!!)を使用して最後のコマンドを1回繰り返すことができますが、30回言うにはどうすればよいですか。
zsh
を使用し、最後のコマンドラインが1つのコマンドまたはパイプラインまたはand-orリスト(つまり、echo x
、echo x | tr x y
、echo x && echo y
、さらには複合{ x; y; }
またはfor
/while
のようなコマンドはループしますが、echo x; echo y
はループしません):
repeat 30 !!
複数のコマンドが含まれている場合でも、前のコマンドラインを繰り返すには、次のコマンドを使用します。
repeat 30 do !!; done
または:
repeat 30 {!!}
bash
を使用して、単純なコマンドのみ(上記の例の中でecho x
の場合のみ)の場合、次のようなヘルパー関数を定義できます。
repeat() {
local n="$1"
shift
while ((n-- > 0)); do
"$@"
done
}
(そして上記のようにrepeat 30 !!
を使用してください)。副作用は、コードが関数で実行されるため、異なる"$@"
、"$#"
が表示され、typeset
などの動作が異なるため、実行できないことです。お気に入り:
eval 'echo "$1"'
repeat 30 !!
zsh
のrepeat 30 {!!}
をエミュレートする別の方法は、次のようなエイリアスを宣言することです。
alias repeat='for i in $(seq'
(未変更の$IFS
と想定)
次に使用します:
repeat 30); { !!; }
私が思いつくことができる最短のものは:
date # or whatever command
for i in {1..30}; do !!; done
1つの方法は、ラインエディターを使用して!!;
を30回挿入することです。
readline
モードのbash
(vi
の行エディター)と同様:
!!;Escdd30p
同等のemacs
モードはzsh
行エディターでは機能しますが、bash
のreadline
では機能しないようです。ただし、代わりにreadline
kbdマクロを使用することもできます。
Kbdマクロを!!;
として定義します。
Ctrl+X(!!;Ctrl+X)
後で30回呼び出すことができます。
Alt+3Alt+0Ctrl+Xe
これは少し見苦しいですが、
eval "`fc -ln -1`;: "{1..10}\;
先頭のスペースは厳密には必要ありませんが、eval
コマンドを履歴に入力しないようにするには、$HISTCONTROL
にはignorespace
(またはignoreboth
)が含まれています。
または:
eval "fc -s $((HISTCMD-2)) "{1..10}\;
そして:
eval 'history -s '{1..10}';fc -s -2;'
Bashの別のループ(この後: https://unix.stackexchange.com/a/372487/9689 )
$PATH
のrepeat
という名前の実行可能ファイルにして、zshと同様の効果を実現します( https://unix.stackexchange.com/a/372484/9689 ):
#!/bin/bash
n=$1
shift 1
for ((x=0; x<$n; ++x)); do
"$@"
done
後でできること:
$ repeat 3 date
要旨: https://Gist.github.com/gwpl/26fefe3a165304f3dedb21009506107f
seq
コマンドは標準の* nixの一部であるため、シェルに依存しません。それとシェルのループ構造を使用すると、次のようなことができます。
for i in $(seq 30); do !!; done
または
for i in `seq 30`; do !!; done