2011/01/17
シェルスクリプトで疑似乱数を取得する
gnu bash には ${RANDOM} というシェル変数が用意されていて、 アクセスするたびに疑似乱数(風)の値が取得できる様だ。 しかし posix 準拠の機能ではなく bash 独自の機能なので拡張性がない。 そこで汎用的な疑似乱数取得の方法として awk (1) を利用した方法を使ってみる。
awk (1) には rand() という関数が組込まれているので
乱数生成ができる。
その際に利用される種(seed)は
srand() という関数で初期化できるので、
これらを利用する事でそこそこの精度の疑似乱数は取得できる。
たとえば 0 〜 m までの疑似乱数は
取得した値から m の剰余を取ることで取得できる。
ただし awk (1) の rand() は仕様として
0 〜 1 までの桁数不定の少数を返すので、
乱数として利用する場合には整数に変換する必要がでてくる。
整数にするために 10n を乗すればよいのだが、
小数点以下の桁数が不定のために小さすぎる n を乗すると
全ての桁が整数化されずに乱数の精度が低くなってしまい、
逆に大きすぎる n を乗すると値が xxx000 の様になってしまい
剰余を取得しても無意味になってしまう。
そこで awk (1) により疑似乱数を取得する場合は rand() で取得した値の前 2 文字 ("0.") を文字列として除外した値から m の剰余とする事で 0 〜 m までの乱数が取得できる。
1#!/bin/sh 2 3awk 'BEGIN{ 4 srand(); 5 print substr(rand(), 3) % '${1:-1}' 6}'
データの型が存在しない(文字列であり数字である) awk (1) ならではの裏技とも言えるだろう。