seq
を使用して、ランダムな数字のリストを生成できることを知っています:1、2、3、4 ...
これらの番号を3、1、4、2などのランダムな順序にしたい...
shuf
を使用してファイルの行をシャッフルできることはわかっています。したがって、seq
を使用してファイルに乱数を書き込み、次にshuf
を使用してそれらをシャッフルするか、何らかのシャッフル関数を作成できます。しかし、これは不必要に複雑に思えます。単一のコマンドで配列内の項目をランダム化する簡単な方法はありますか?
出力をshuf
にパイプするだけです。
$ seq 100 | shuf
$ seq 10 | shuf
2
6
4
8
1
3
10
7
9
5
出力を水平にしたい場合は、それをpaste
にパイプします。
$ seq 10 | shuf | paste - -s -d ' '
1 6 9 3 8 4 10 7 2 5
$ seq 10 | shuf | paste - -s -d ' '
7 4 6 1 8 3 10 5 9 2
$ seq 10 | shuf | paste - -s -d ' '
9 8 3 6 1 2 10 4 7 5
間にコンマを入れたいですか?区切り文字をpaste
に変更します。
$ seq 10 | shuf | paste - -s -d ','
2,4,9,1,8,7,3,5,10,6
単一のコマンドで配列内の項目をランダム化する簡単な方法はありますか?
10進整数の配列があると仮定します。
arr=(4 8 14 18 24 29 32 37 42)
printf
およびshuf
を使用して、配列の要素をランダム化できます。
$ arr=($(printf "%d\n" "${arr[@]}" | shuf))
$ echo "${arr[@]}"
4 37 32 14 24 8 29 42 18
(上記は$IFS
を変更していないことを前提としています)。
必要なのが2つの整数間の乱数、たとえば10
と20
の場合、-i
オプションを使用すれば、shuf
以外の追加のプロセスは必要ありません。
$ shuf -i 10-20
12
10
20
14
16
19
13
11
18
17
15
man shuf
からの引用:
-i, --input-range=LO-HI
treat each number LO through HI as an input line
printf '%s, ' `seq 1 10 | shuf`
for
ループも必要ありません。
7, 3, 4, 10, 2, 9, 1, 8, 5, 6,
それらをシェル配列で取得するには、次のようにします。
( set -- $(seq 1 10 | shuf) ; printf '%s, ' "$@" )
5, 9, 7, 2, 4, 3, 6, 1, 10, 8,
そして、それらはあなたのシェル配列にあります。
それらをShell配列で取得する場合、printf
も必要ありません。
( set -- $(seq 1 10 | shuf); IFS=, ; echo "$*" )
9,4,10,3,1,2,7,5,6,8
ちなみに、seq
とprintf
は、お互いのために作られたものです。たとえば、文字列を1000回繰り返したい場合はどうでしょうか。
printf 'a string\n%.0b' `seq 1 1000`
a string
... 999 a string
行後...
a string
または...
printf 'a string,%.0b' `seq 1 10`
a string,a string,a string,a string,a string,a string,a string,a string,a string,a string,
コマンドを39回実行したいのですが?
printf 'echo "run %d"\n' `seq 1 39` | . /dev/stdin
run 1
... 38 run
行後...
run 39
shuf
コマンドを使用して、出力をランダム化できます。
%> for x in $(seq 1 10 | shuf); do echo -n "$x "; done; echo
4 10 8 7 1 6 3 5 2 9
POSIXly、min
からmax
までの10進整数のシャッフルリストを生成するには:
_awk -v min=1 -v max=10 'BEGIN{
for (i = min; i <= max; i++) a[i] = i
srand()
for (i = min; i <= max; i++) {
j = int(Rand() * (max - min + 1)) + min
tmp = a[i]; a[i] = a[j]; a[j] = tmp
}
for (i = min; i <= max; i++) print a[i]
}'
_
多くのawk実装では、そのコマンドを同じ1秒以内に2回実行すると同じ結果が生成されることに注意してください(srand()
は現在の時間に基づいて疑似ランダムジェネレーターにシードします)。