私は時々このようにbashコマンドラインを実行します。
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
some_command
を連続して何度も実行する - この場合は10回。
多くの場合、some_command
は実際には一連のコマンドまたはパイプラインです。
もっと簡潔な方法はありますか?
for run in {1..10}
do
command
done
簡単にコピー&ペーストしたい人のためのワンライナーとして:
for run in {1..10}; do command; done
定数を使う:
for ((n=0;n<10;n++)); do some_command; done
変数を使用する(数学式を含めることができます):
x=10 for ((n=0; n < (x / 2); n++)); do some_command; done
それをハックするためのもう一つの簡単な方法:
seq 20 | xargs -Iz echo "Hi there"
エコーを20回実行します。
seq 20 | xargs -Iz echo "Hi there z"
が出力することに注意してください。
こんにちは1
こんにちは2
...
Zshシェルを使用している場合
repeat 10 { echo 'Hello' }
ここで、10はコマンドが繰り返される回数です。
GNU Parallelを使用すると、次のことができます。
parallel some_command ::: {1..1000}
引数として数値を必要とせず、一度に1つのジョブだけを実行する場合は、次のようにします。
parallel -j1 -N0 some_command ::: {1..1000}
紹介ビデオで簡単な紹介をご覧ください。 https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
チュートリアルを進めます( http://www.gnu.org/software/parallel/parallel_tutorial.html )。あなたはそれのためにあなたを愛してラインを指揮します。
Bash設定ファイル内の単純な関数(~/.bashrc
がよくあります)でうまくいくでしょう。
function runx() {
for ((n=0;n<$1;n++))
do ${*:2}
done
}
このように呼んでください。
$ runx 3 echo 'Hello world'
Hello world
Hello world
Hello world
あなたの例のもう一つの形:
n=0; while (( n++ < 10 )); do some_command; done
xargs
はfast:です。
#!/usr/bin/bash
echo "while loop:"
n=0; time while (( n++ < 10000 )); do /usr/bin/true ; done
echo -e "\nfor loop:"
time for ((n=0;n<10000;n++)); do /usr/bin/true ; done
echo -e "\nseq,xargs:"
time seq 10000 | xargs -I{} -P1 -n1 /usr/bin/true
echo -e "\nyes,xargs:"
time yes x | head -n10000 | xargs -I{} -P1 -n1 /usr/bin/true
echo -e "\nparallel:"
time parallel --will-cite -j1 -N0 /usr/bin/true ::: {1..10000}
現代の64ビットLinuxでは、次のようになります。
while loop:
real 0m2.282s
user 0m0.177s
sys 0m0.413s
for loop:
real 0m2.559s
user 0m0.393s
sys 0m0.500s
seq,xargs:
real 0m1.728s
user 0m0.013s
sys 0m0.217s
yes,xargs:
real 0m1.723s
user 0m0.013s
sys 0m0.223s
parallel:
real 0m26.271s
user 0m4.943s
sys 0m3.533s
これは、すべてのBashで解釈されるxargs
およびfor
のループではなく、while
コマンドが/usr/bin/true
コマンドを複数回生成する単一のネイティブプロセスであるため、意味があります。もちろん、これは単一のコマンドに対してのみ機能します。ループを繰り返すたびに複数のコマンドを実行する必要がある場合は、xargsにsh -c 'command1; command2; ...'
を渡すのと同じくらいの速さか、おそらくより速いでしょう。
また、-P1
を-P8
に変更して、並行して8つのプロセスを生成し、速度を大幅に向上させることもできます。
GNU parallelがそんなに遅いのかわかりません。私はそれがxargsに匹敵するだろうと思っていたでしょう。
xargsとseqが役立ちます
function __run_times { seq 1 $1| { shift; xargs -i -- "$@"; } }
景色 :
abon@abon:~$ __run_times 3 echo hello world
hello world
hello world
hello world
for _ in {1..10}; do command; done
変数を使用する代わりにアンダースコアに注意してください。
一つには、それを関数にまとめることができます:
function manytimes {
n=0
times=$1
shift
while [[ $n -lt $times ]]; do
$@
n=$((n+1))
done
}
ようにそれを呼ぶ:
$ manytimes 3 echo "test" | tr 'e' 'E'
tEst
tEst
tEst
定期的に実行しても問題ない場合は、次のコマンドを実行して1秒ごとに無期限に実行できます。 n回実行するために他のカスタムチェックを配置することができます。
watch -n 1 some_command
変更を視覚的に確認したい場合は、ls
コマンドの前に--differences
を追加してください。
OSXのmanページによると、
--cumulativeオプションを使用すると、「スティッキー」が強調表示され、これまでに変更されたすべてのポジションが連続して表示されます。 -tまたは--no-titleオプションを指定すると、間隔、コマンド、および現在の時刻を画面上部に表示するヘッダーと、それに続く空白行がオフになります。
Linux/Unixのmanページが見つかります こちら
繰り返しはループの数を表す整数です。
repeat=10
for n in $(seq $repeat);
do
command1
command2
done
さらに別の答え:空のパラメータにパラメータ展開を使用します。
# calls curl 4 times
curl -s -w "\n" -X GET "http:{,,,}//www.google.com"
Centos 7とMacOSでテスト済み。
ちょっと素朴ですが、これは私が私の頭の上から覚えているものです:
for i in 1 2 3; do
some commands
done
@ joe-kobergの回答とよく似ています。特にあなたが多くの繰り返しを必要とするなら、彼はより優れています、私がbash
をあまり使っていないので、私が他の構文を覚えるのはもっと難しいです。少なくともスクリプトを書くためではないということです。
スクリプトファイル
bash-3.2$ cat test.sh
#!/bin/bash
echo "The argument is arg: $1"
for ((n=0;n<$1;n++));
do
echo "Hi"
done
そして以下の出力
bash-3.2$ ./test.sh 3
The argument is arg: 3
Hi
Hi
Hi
bash-3.2$
Forループはおそらくそれを行うための正しい方法ですが、ここでは楽しい代替案です:
echo -e {1..10}"\n" |xargs -n1 some_command
呼び出しのパラメータとして反復数が必要な場合は、次のようにします。
echo -e {1..10}"\n" |xargs -I@ echo now I am running iteration @
編集:上記の解決策は単純なコマンド実行(パイプなしなど)でのみスムーズに機能すると正しくコメントされていました。あなたはいつでもsh -c
を使ってもっと複雑なことをすることができますが、それだけの価値はありません。
私が使用するもう1つの方法は、通常、以下の機能です。
rep() { s=$1;shift;e=$1;shift; for x in `seq $s $e`; do c=${@//@/$x};sh -c "$c"; done;}
今、あなたはそれをと呼ぶことができます:
rep 3 10 echo iteration @
最初の2つの数字は範囲を示します。 @
は反復数に変換されます。これでパイプでもこれを使うことができます。
rep 1 10 "ls R@/|wc -l"
とディレクトリR1 .. R10内のファイルの数を与えます。
(bashref)Looping Constructs に記載されているfor
の代替形式はどうですか。