コンソール上で、ランダムな数字を出力させたいというのがあったので、少し調べてみた。 結構いろいろな方法があるようだ。

1.環境変数「$RANDOM」を用いる

bashでは、環境変数「$RANDOM」を用いることで0~32767までの数字をランダムに出力させることができる。 0から数えるので、+100とかで指定すると0~99までしか出力しないので注意。

bash
echo $RANDOM # 0~32767までの範囲で出力する echo $((RANDOM%+101)) # 0~100までの範囲で出力する echo $((RANDOM%100+101)) # 101~200までの範囲で出力する
shell
[root@BS-PUB-CENT7-01 ~]# echo $RANDOM # 0~32767までの範囲で出力する 1885 [root@BS-PUB-CENT7-01 ~]# echo $RANDOM # 0~32767までの範囲で出力する 10607 [root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%+101)) # 0~100までの範囲で出力する 76 [root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%+101)) # 0~100までの範囲で出力する 22 [root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%100+101)) # 100~200までの範囲で出力する 107 [root@BS-PUB-CENT7-01 ~]# echo $((RANDOM%100+101)) # 100~200までの範囲で出力する 138

複数の数字を得る場合は、以下のようにコマンドを実行することで指定回数繰り返し、ランダムな数字を複数出力させることができる。

bash
yes 'echo $((RANDOM%+101))' | head -10 | bash # headで実行回数を指定
shell
[root@BS-PUB-CENT7-01 ~]# yes 'echo $((RANDOM%+101))' | head -10 | bash # headで実行回数を指定 42 48 51 8 77 54 60 2 14 97

2./dev/urandom or /dev/randomを用いる

「$RANDOM」に比べるとちょっと扱いづらいけど、「/dev/urandom」もしくは「/dev/random」を読み込むことで、ランダムな文字列・値を取得することができる。 そのままcatなどで開いても扱えないので、odで加工するのが一般的。 2のべき乗の範囲の値が取得されるようなので、範囲をちゃんと指定する場合はさらに加工が必要になりそう。 とりあえず、以下のようにコマンドを実行することで0~100までの値を取得できる。

bash
echo $(($(od -vAn -N1 -tu < /dev/urandom) % 101 ))
shell
[root@BS-PUB-CENT7-01 ~]# yes 'echo $(($(od -vAn -N1 -tu < /dev/urandom) % 101 ))' | head -10 | bash 70 31 0 44 30 30 29 7 14 68

3.jotコマンドを用いる

seqのように利用できるBSD系のコマンドでjotというのがあるが、これには「-r」というランダムな値を出力するオプションが付いている。 Debian/Ubuntu系であればaptでインストールできる。 以下のようにjotコマンドを実行することで、0~100までのランダムな値を10個出力させている。

bash
jot -r 10 0 100
shell
blacknon@BS-PUB-UBUNTU-01:~$ jot -r 10 0 100 61 50 44 54 55 88 77 5 20 71

4.seq + shufで頑張る

jotがないorインストールできない場合、とりあえずseqとshufで似たようなことはできる(処理効率悪いと思うけど)。 とりあえず、以下のようにコマンドを実行することで0~100のランダムな値を1個得ることができる。

bash
seq 0 100 | shuf | head -1
shell
blacknon@BS-PUB-UBUNTU-01:~$ seq 0 100 | shuf | head -1 42 blacknon@BS-PUB-UBUNTU-01:~$ yes 'seq 0 100 | shuf | head -1' | head -10 | bash 20 60 14 3 20 64 24 0 33 64

5.awkを用いる

awkのrand関数を用いることで、ランダムな数字を取得できる。 srand()で初期化が必要なのだが、これは現在時刻(秒)を元に計算しているため、1秒経過しないとランダムな値でも同じ値が出力されてしまうので注意。

bash
awk 'BEGIN{srand(1);print int(rand()*100)}'
shell
blacknon@BS-PUB-UBUNTU-01:~$ awk 'BEGIN{srand();print int(rand()*100)}' 88 blacknon@BS-PUB-UBUNTU-01:~$ awk 'BEGIN{srand();print int(rand()*100)}' 60 blacknon@BS-PUB-UBUNTU-01:~$ # 連続で実行しても、秒が経過するまでは同じ値が出力される。 blacknon@BS-PUB-UBUNTU-01:~$ yes "awk 'BEGIN{srand();print int(rand()*100)}'" | head -10 | bash 70 70 70 70 70 70 70 70 70 70

6.Perlで出力する

Perlで出力する場合はこんな感じ。

bash
perl -e 'printf ("%d\n",int(rand($MAX - $MIN)))' perl -e 'foreach $i (1..n) {printf ("%d\n",int(rand(MAX - MIN)))}'
shell
blacknon@BS-PUB-UBUNTU-01:~$ perl -e 'printf ("%d\n",int(rand(100 - 0)))' 82 blacknon@BS-PUB-UBUNTU-01:~$ perl -e 'foreach $i (1..10) {printf ("%d\n",int(rand(100 - 0)))}' 6 90 53 1 25 68 93 97 9 82

7.Rubyで出力する

Rubyでやる場合はこんなん。

bash
ruby -e 'printf("%d\n",Random.rand(MIN...MAX))' ruby -e 'ran= 0..n;ran.each{printf("%d\n",Random.rand(MIN...MAX))}'
shell
blacknon@BS-PUB-UBUNTU-01:~$ ruby -e 'printf("%d\n",Random.rand(0...100))' 71 blacknon@BS-PUB-UBUNTU-01:~$ ruby -e 'ran= 0..10;ran.each{printf("%d\n",Random.rand(0...100))}' 78 71 18 12 49 92 32 7 72 35 73

8.Pythonで出力する

Pythonの場合。

bash
python -c 'from random import randint; print(randint(MIN,MAX))' python -c 'from random import randint; print "\n".join(map(str,[randint(MIN,MAX) for p in range(0,n)]))'
shell
blacknon@BS-PUB-UBUNTU-01:~$ python -c 'from random import randint; print(randint(0,100))' 91 blacknon@BS-PUB-UBUNTU-01:~$ python -c 'from random import randint; print "\n".join(map(str,[randint(0,100) for p in range(0,10)]))' 93 49 23 9 29 72 23 53 34 53