Comment randomiser la sortie de seq?


11

Je sais que je peux utiliser seqpour générer une liste aléatoire de nombres: 1, 2, 3, 4 ...

Je veux obtenir ces nombres dans un ordre aléatoire comme 3, 1, 4, 2 ...

Je sais que je peux utiliser shufpour mélanger les lignes d'un fichier. Je pourrais donc utiliser seqpour écrire des nombres aléatoires dans un fichier, puis shufpour les mélanger - ou pour écrire une sorte de fonction de lecture aléatoire. Mais cela semble inutilement complexe. Existe-t-il un moyen plus simple de randomiser les éléments d'un tableau avec une seule commande?

Réponses:


16

Vous pouvez simplement diriger la sortie vers shuf.

$ seq 100 | shuf

Exemple

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

Si vous souhaitez que la sortie soit horizontale, dirigez-la vers 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 

Vous le voulez avec des virgules entre les deux? Remplacez le délimiteur par paste:

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

Mais vous devez formater d'une manière ou d'une autre pour les mettre sur une seule ligne avec des virgules. echo $(seq 10 | shuf)se rapproche mais ne fait pas les virgules.
mikeserv

C'est horizontal avant paste...
mikeserv

@mikeserv - l'a changé.
slm

Ouais. Voilà. Je pastene savais pas ça. Merci de m'avoir appris. Ayez un vote positif.
mikeserv

@mikeserv - oui, parcourez le site en regardant le mien, celui de Stéphane ou de Gilles A en utilisant joinet paste. Ces 2 outils sont extrêmement puissants.
slm

3

Existe-t-il un moyen plus simple de randomiser les éléments d'un tableau avec une seule commande?

En supposant que vous ayez un tableau d'entiers décimaux:

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

Vous pouvez utiliser printfet shufpour randomiser les éléments du tableau:

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

(ce qui précède suppose que vous n'avez pas modifié $IFS).


Si vous n'avez besoin que de nombres aléatoires entre deux entiers, disons 10et 20, vous n'avez pas besoin de processus supplémentaires autrement qu'en shufutilisant l' -ioption:

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

Citant de man shuf:

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

Shucks. J'ai vu cela aussi shuf --helpmais j'ai essayé d'utiliser shuf -i 1 10sans intervenir -dash.oh bien, bon travail - ayez mon vote positif.
mikeserv

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

Vous n'avez même pas besoin d'une forboucle.

PRODUCTION

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

Pour les placer dans un tableau shell, vous devez:

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

PRODUCTION

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

Et puis ils sont dans votre tableau shell.

Si vous les obtenez dans le tableau shell, vous n'avez même pas besoin printf:

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

PRODUCTION

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

Soit dit en passant, seqet printfsont un peu faits l'un pour l'autre. Par exemple, si je veux répéter une chaîne 1000 fois?

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

PRODUCTION

a string

... 999 a stringlignes plus tard ...

a string

Ou...

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

PRODUCTION

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

Je veux exécuter une commande 39 fois?

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

PRODUCTION

run 1

... 38 runlignes plus tard ...

run 39

1

Vous pouvez utiliser la shufcommande pour randomiser la sortie, par exemple

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

1

POSIX, pour générer une liste mélangée des entiers décimaux de minà 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]
}'

Gardez à l'esprit qu'avec de nombreuses implémentations awk, l'exécution de cette commande deux fois dans la même seconde produira le même résultat (en tant que srand()générateur du générateur pseudo-aléatoire en fonction de l'heure actuelle).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.