awkで乱数を使いたい時は rand()
関数を使います。
$ echo | awk '{print rand()}' 0.827331
rand()
は0~1までの乱数を発生させます。そのため、例えば1〜10までの値にしたい時は以下のように書く必要があります。
$ echo | awk '{print int(rand()*10)+1}' 7
このように非常にシンプルな関数なのですが、注意しなければならない挙動があります。
同じ乱数しか生成しない問題
awkにはgawkやnawk, mawkなど色々な実装があるのですが、一部の実装では乱数の値がビルド時に決定してしまい、同じ値しか返さないことがあります。例えば、Macに入っているawkコマンド、nawk(new awk)がこれに当てはまります。以下、Macで複数回同じrandコマンドを実行した例を貼り付けます。
~$ echo | awk '{print rand()}' 0.840188 ~$ echo | awk '{print rand()}' 0.840188 ~$ echo | awk '{print rand()}' 0.840188
rand()
が返す値は常に一定です。
次に、Ubuntuのawk、gwk(GNU awk)の例を貼り付けます。
$ echo | awk '{print rand()}' 0.0983234 $ echo | awk '{print rand()}' 0.456071 $ echo | awk '{print rand()}' 0.456071 $ echo | awk '{print rand()}' 0.315948
異なる値が生成されています。が、一部値が被っているのが気になります。
解決策
nawkでもgawkでも解決策は同様で、srand()
関数でシード値を毎回設定するようにします。
$ echo | awk 'BEGIN{srand()} {print rand()}' 0.550617
こうすれば処理のたびに srand()
関数が実行され、 rand()
で使用されるシード値が毎回新しい値になります。
以下のように10回連続で rand()
しても毎回違う値になります。
$ seq 10 | awk 'BEGIN{srand()} {print rand()}' 0.787021 0.291794 0.777201 0.619548 0.505395 0.399438 0.888092 0.218917 0.96164 0.751791
srand()を除いて上のコードを実行するとnawkでもgawkでも同じ値になるのでぜひ試してみてください。ではでは!
参考: