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

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

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

echo $RANDOM # 0~32767までの範囲で出力する
echo $((RANDOM%+101)) # 0~100までの範囲で出力する
echo $((RANDOM%100+101)) # 101~200までの範囲で出力する
[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

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

yes 'echo $((RANDOM%+101))' | head -10 | bash # headで実行回数を指定
[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までの値を取得できる。

echo $(($(od -vAn -N1 -tu < /dev/urandom) % 101 ))
[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個出力させている。

jot -r 10 0 100
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個得ることができる。

seq 0 100 | shuf | head -1
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秒経過しないとランダムな値でも同じ値が出力されてしまうので注意。

awk 'BEGIN{srand(1);print int(rand()*100)}'
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で出力する場合はこんな感じ。

perl -e 'printf ("%d\n",int(rand($MAX - $MIN)))'
perl -e 'foreach $i (1..n) {printf ("%d\n",int(rand(MAX - MIN)))}'
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でやる場合はこんなん。

ruby -e 'printf("%d\n",Random.rand(MIN...MAX))'
ruby -e 'ran= 0..n;ran.each{printf("%d\n",Random.rand(MIN...MAX))}'
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の場合。

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)]))'
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