Come randomizzare l'output da seq?


11

So che posso usare seqper generare un elenco casuale di numeri: 1, 2, 3, 4 ...

Voglio ottenere quei numeri in un ordine casuale come 3, 1, 4, 2 ...

So che posso usare shufper mescolare le linee di un file. Quindi potrei usare seqper scrivere numeri casuali su un file e poi usarli shufper mescolarli - o scrivere una sorta di funzione shuffle. Ma questo sembra inutilmente complesso. Esiste un modo più semplice per randomizzare gli elementi in un array con un singolo comando?

Risposte:


16

Puoi semplicemente reindirizzare l'output a shuf.

$ seq 100 | shuf

Esempio

$ seq 10 | shuf
2
6
4
8
1
3
10
7
9
5

Se si desidera che l'output sia orizzontale, reindirizzarlo a 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 

Lo vuoi con una virgola in mezzo? Cambia il delimitatore in paste:

$ seq 10 | shuf | paste - -s -d ','
2,4,9,1,8,7,3,5,10,6

Ma devi formattarlo in qualche modo per metterli su una riga con le virgole. echo $(seq 10 | shuf)si avvicina ma non fa le virgole.
Mikeserv,

È orizzontale prima paste...
mikeserv

@mikeserv - l'ha cambiato in giro.
slm

Si. Ecco qua. Non lo sapevo paste. Grazie per avermi insegnato. Avere un voto.
Mikeserv,

@mikeserv - sì, leggi il sito guardando il mio, quello di Stephane o Gilles A usando joine paste. Quei 2 strumenti sono estremamente potenti.
slm

3

Esiste un modo più semplice per randomizzare gli elementi in un array con un singolo comando?

Supponendo che tu abbia una matrice di numeri interi decimali:

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

È possibile utilizzare printfe shufrandomizzare gli elementi dell'array:

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

(quanto sopra presuppone che tu non abbia modificato $IFS).


Se tutto ciò di cui hai bisogno sono numeri casuali tra due numeri interi, diciamo 10e 20, non hai bisogno di ulteriori processi se non shufusando l' -iopzione:

$ shuf -i 10-20
12
10
20
14
16
19
13
11
18
17
15

Citando da man shuf:

   -i, --input-range=LO-HI
          treat each number LO through HI as an input line

Shucks. L'ho visto anche shuf --helpio, ma ho provato a usarlo shuf -i 1 10senza l'intervento -dash.oh beh, buon lavoro - ho il mio voto.
Mikeserv,

2
printf '%s, ' `seq 1 10 | shuf`

Non hai nemmeno bisogno di un forciclo.

PRODUZIONE

7, 3, 4, 10, 2, 9, 1, 8, 5, 6,

Per ottenerli in un array di shell, esegui:

( set -- $(seq 1 10 | shuf) ; printf '%s, ' "$@" )

PRODUZIONE

5, 9, 7, 2, 4, 3, 6, 1, 10, 8,

E poi sono nel tuo array di shell.

Se li ottieni nell'array di shell, non hai nemmeno bisogno di printf:

( set -- $(seq 1 10 | shuf); IFS=, ; echo "$*" )

PRODUZIONE

9,4,10,3,1,2,7,5,6,8

A proposito, seqe printfsono un po 'fatti l'uno per l'altro. Ad esempio, se voglio ripetere una stringa 1000 volte?

printf 'a string\n%.0b' `seq 1 1000`

PRODUZIONE

a string

... 999 a stringrighe dopo ...

a string

O...

printf 'a string,%.0b' `seq 1 10`

PRODUZIONE

a string,a string,a string,a string,a string,a string,a string,a string,a string,a string,

Voglio eseguire un comando 39 volte?

printf 'echo "run %d"\n' `seq 1 39` | . /dev/stdin

PRODUZIONE

run 1

... 38 runrighe dopo ...

run 39

1

È possibile utilizzare il shufcomando per randomizzare l'output, ad es

%> 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, per generare un elenco casuale degli interi decimali da mina 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]
}'

Attenzione che con molte implementazioni awk, eseguire quel comando due volte nello stesso secondo produrrà lo stesso risultato (come srand()seed il generatore pseudo-casuale basato sull'ora corrente).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.