Como randomizar a saída de seq?

11

Eu sei que posso usar seqpara gerar uma lista aleatória de números: 1, 2, 3, 4 ...

Quero colocar esses números em uma ordem aleatória como 3, 1, 4, 2 ...

Eu sei que posso usar shufpara embaralhar as linhas de um arquivo. Então, eu poderia seqescrever números aleatórios em um arquivo e depois shufembaralhá-los - ou escrever algum tipo de função aleatória. Mas isso parece desnecessariamente complexo. Existe uma maneira mais simples de randomizar os itens em uma matriz com um único comando?

bernie2436
fonte

Respostas:

16

Você pode apenas canalizar a saída para shuf.

$ seq 100 | shuf

Exemplo

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

Se você deseja que a saída seja horizontal, faça o pipe para 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 

Quer com vírgulas no meio? Mude o delimitador para paste:

$ seq 10 | shuf | paste - -s -d ','
2,4,9,1,8,7,3,5,10,6
slm
fonte
Mas você precisa formatar de alguma forma para colocá-los em uma linha com vírgulas. echo $(seq 10 | shuf)chega perto, mas não faz vírgulas.
precisa saber é o seguinte
É horizontal antes paste...
mikeserv
@mikeserv - mudou tudo.
Slm
Sim. Ai está. Eu não sabia pasteque fiz isso. Obrigado por me ensinar. Tenha um voto positivo.
mikeserv
@ mikeserv - sim, leia o site olhando para o meu, o Stephane ou o Gilles A usando joine paste. Essas 2 ferramentas são extremamente poderosas.
Slm
3

Existe uma maneira mais simples de randomizar os itens em uma matriz com um único comando?

Supondo que você tenha uma matriz de números inteiros decimais:

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

Você pode usar printfe shufpara randomizar os elementos da matriz:

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

(o acima pressupõe que você não modificou $IFS).


Se tudo o que você precisa são números aleatórios entre dois números inteiros, digamos 10e 20, você não precisa de nenhum processo extra além de shufusar a -iopção:

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

Citação de man shuf:

   -i, --input-range=LO-HI
          treat each number LO through HI as an input line
devnull
fonte
Shucks. Eu vi isso também, shuf --helpmas tentei usar shuf -i 1 10sem a intervenção, -dash.oh bem, bom trabalho - tenho meu voto positivo.
precisa saber é o seguinte
2
printf '%s, ' `seq 1 10 | shuf`

Você nem precisa de um forloop.

RESULTADO

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

Para obtê-los em uma matriz shell, você deve:

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

RESULTADO

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

E então eles estão em sua matriz de shell.

Se você obtê-los na matriz shell, você nem precisa printf:

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

RESULTADO

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

A propósito, seqe printfsão feitos um para o outro. Por exemplo, se eu quiser repetir uma string 1000 vezes?

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

RESULTADO

a string

... 999 a stringlinhas depois ...

a string

Ou...

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

RESULTADO

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

Eu quero executar um comando 39 vezes?

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

RESULTADO

run 1

... 38 runlinhas depois ...

run 39
mikeserv
fonte
1

Você pode usar o shufcomando para randomizar a saída, por exemplo

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

POSIXly, para gerar uma lista aleatória dos números inteiros decimais de minpara 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]
}'

Observe que, com muitas implementações do awk, executar esse comando duas vezes no mesmo segundo produzirá o mesmo resultado (como srand()semear o gerador pseudo-aleatório com base no horário atual).

Stéphane Chazelas
fonte