seqからの出力をランダム化する方法は?


11

seqは番号のランダムなリストを生成するために使用できることを知っています:1、2、3、4 ...

これらの番号を3、1、4、2などのランダムな順序にしたい...

shufはファイルの行をシャッフルするのに使用できることを知っています。したがってseq、乱数をファイルに書き込んでshufからそれらをシャッフルするために使用したり、ある種のシャッフル関数を書き込んだりすることができます。しかし、これは不必要に複雑に思えます。単一のコマンドで配列内の項目をランダム化する簡単な方法はありますか?

回答:


16

出力をにパイプするだけ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

しかし、コンマを使用して1行で取得するには、なんらかの方法でフォーマットする必要があります。echo $(seq 10 | shuf)近づいてきますが、コンマは行いません。
mikeserv 2014

それは前に水平pasteです...
mikeserv 2014

@mikeserv-変更しました。
slm

うん。どうぞ。知らpasteなかった。教えてくれてありがとう 賛成票を持っています。
mikeserv 2014

@mikeserv-ええ、私のサイト、Stephane'sまたはGilles Aが使っているjoinとを見て読んでくださいpaste。これら2つのツールは非常に強力です。
slm

3

単一のコマンドで配列内の項目をランダム化する簡単な方法はありますか?

10進整数の配列があると仮定します。

arr=(4 8 14 18 24 29 32 37 42)

printfshufを使用して、配列の要素をランダム化できます。

$ arr=($(printf "%d\n" "${arr[@]}" | shuf))
$ echo "${arr[@]}"
4 37 32 14 24 8 29 42 18

(上記は、変更していないことを前提としています$IFS)。


必要なのが2つの整数の間の乱数、たとえば10とだけ20である場合shuf-iオプションを使用する以外に追加のプロセスは必要ありません。

$ 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

くそったれ。私もそれを見ましたshuf --helpshuf -i 1 10、介入せずに使用しようとしました-dash.
mikeserv 14

2
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,

そして、それらはあなたのシェル配列にあります。

それらをシェル配列で取得する場合、必要はありません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

1

shufコマンドを使用して、出力をランダム化できます。

%> for x in $(seq 1 10 | shuf); do echo -n "$x "; done; echo
4 10 8 7 1 6 3 5 2 9 

1

POSIXly、toからmintoまでの10進整数のシャッフルリストを生成するにはmax

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()現在の時刻に基づいて疑似ランダムジェネレーターにシードします)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.