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) ならではの裏技とも言えるだろう。


Copyright © Mitzyuki IMAIZUMI 2008,2009. All rights reserved.