私は次のような基本的なループを探しています:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
しかし、Bashの場合。
このサイトから:
for i in $(seq 1 10);
do
echo $i
done
for ((i = 0 ; i < max ; i++ )); do echo "$i"; done
Bashfor
は、変数(イテレーター)と、イテレーターが反復する単語のリストで構成されます。
したがって、単語のリストが限られている場合は、次の構文に入れてください。
for w in word1 word2 word3
do
doSomething($w)
done
おそらく、いくつかの数値に沿って反復したいので、seq
コマンドを使用して数値のリストを生成できます:(たとえば、1から100まで)
seq 1 100
そしてそれをforループで使用します:
for n in $(seq 1 100)
do
doSomething($n)
done
$(...)
構文に注意してください。これはBashの動作であり、あるコマンド(この場合はfrom seq
)から別のコマンド()に出力を渡すことができますfor
。
これは、次のように、パス内のすべてのディレクトリを反復処理する必要がある場合に非常に便利です。
for d in $(find $somepath -type d)
do
doSomething($d)
done
リストを生成する可能性は無限大です。
Bash 3.0 以降では、次の構文を使用できます。
for i in {1..10} ; do ... ; done
...これにより、外部プログラムを生成してシーケンスを展開することを回避できます (などseq 1 10
)。
もちろん、これにはfor(())
ソリューションと同じ問題があり、Bash や特定のバージョン (これが重要な場合) に結び付けられています。
Bashの組み込みヘルプをお試しください:
help for
for: for NAME [in WORDS ... ;] do COMMANDS; done
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
Equivalent to
(( EXP1 ))
while (( EXP2 )); do
COMMANDS
(( EXP3 ))
done
EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is
omitted, it behaves as if it evaluates to 1.
#! /bin/bash
function do_something {
echo value=${1}
}
MAX=4
for (( i=0; i<MAX; i++ )) ; {
do_something ${i}
}
以下は、古いシェルでも機能し、大きなカウントに対しても効率的な例です。
Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'
しかし、内で役立つことを頑張ってくださいawk
: awkスクリプトでシェル変数を使用するにはどうすればよいですか?
私は通常、標準の forループをわずかに変更したものを使用するのが好きです。私はよくこれを使用して、一連のリモート ホストでコマンドを実行します。Bash のブレース展開を利用して、非数値の forループを作成できる for ループを作成します。
例:
フロントエンド ホスト 1 ~ 5 とバックエンド ホスト 1 ~ 3 で uptime コマンドを実行します。
% for host in {frontend{1..5},backend{1..3}}.mycompany.com
do ssh $host "echo -n $host; uptime"
done
私は通常、上記のより読みやすいバージョンではなく、行末にセミコロンを付けた単一行コマンドとしてこれを実行します。重要な使用上の考慮事項は、ブレースを使用すると、文字列に挿入される複数の値を指定できるようになり (たとえば、pre{foo,bar}post の結果が prefoopost、prebarpost になる)、二重のピリオドを使用してカウント/シーケンスが可能になることです (a. .z など)。ただし、二重ピリオド構文は Bash 3.0 の新機能です。それ以前のバージョンはこれをサポートしていません。
Bash だけに興味がある場合は、上記の "for(( ... ))" ソリューションが最適ですが、すべての Unice で動作するPOSIX SH 準拠のものが必要な場合は、"expr を使用する必要があります。 " と "while" は、"(())" または "seq" または "i=i+1" がさまざまなシェル間でそれほど移植性がないためです。
私はファイルを処理するためにこれのバリエーションを常に使用しています...
*.log内のファイルの場合; echo "Do stuff with:$ files"; echo "次の処理を行う:$ files"; 終わり;
ファイルのリストの処理に関心がある場合は、ファイルの-execdirオプションを調べてください。