Seq çıktısı nasıl rastgele?


11

seqRasgele bir sayı listesi oluşturmak için kullanabileceğimi biliyorum : 1, 2, 3, 4 ...

Bu sayıları 3, 1, 4, 2 gibi rastgele bir sıraya koymak istiyorum ...

shufBir dosyanın satırlarını karıştırmak için kullanabileceğimi biliyorum . Bu yüzden seqbir dosyaya rastgele sayılar yazmak ve daha sonra shufbunları karıştırmak için veya bir tür karışıklık işlevi yazmak için kullanabilirsiniz . Ama bu gereksiz yere karmaşık görünüyor. Bir dizideki öğeleri tek bir komutla rastgele ayarlamanın daha kolay bir yolu var mı?

Yanıtlar:


16

Çıkışı sadece boru hattına bağlayabilirsiniz shuf.

$ seq 100 | shuf

Misal

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

Çıktının yatay olmasını istiyorsanız, boruya bağlayın 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 

Arasında virgül kullanmak ister misiniz? Sınırlayıcıyı şu şekilde değiştirin paste:

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

Ama bir şekilde virgülle bir satıra yerleştirmek için bir şekilde biçimlendirmeniz gerekiyor. echo $(seq 10 | shuf)yaklaşıyor ama virgül yapmıyor.
mikeserv

Daha önce yatay paste...
mikeserv

@mikeserv - değiştirdi.
slm

Evet. İşte böyle. Bunu bilmiyordum paste. Bana öğrettiğiniz için teşekkürler. Bir oy verin.
mikeserv

@mikeserv - evet siteyi okurken mayın, Stephane's veya Gilles A'yı kullanarak joinve kullanın paste. Bu 2 araç son derece güçlü.
slm

3

Bir dizideki öğeleri tek bir komutla rastgele ayarlamanın daha kolay bir yolu var mı?

Bir ondalık basamak tamsayı diziniz olduğunu varsayarsak:

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

Sen kullanabilirsiniz printfve shufdizinin elemanlarını rastgele kullanmak için:

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

(yukarıda değişiklik yapmadığınızı varsayar $IFS).


Tüm ihtiyacınız iki tamsayı arasında rastgele sayılar ise, demek 10ve 20sen başka ekstra süreçleri gerekmez shufkullanarak -iseçeneği:

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

Alıntı man shuf:

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

Shucks. Bunu da gördüm shuf --helpama shuf -i 1 10araya girmeden kullanmaya çalıştım -dash., iyi iş - benim oyum var.
mikeserv

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

Döngüye bile ihtiyacınız yok for.

ÇIKTI

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

Onları bir kabuk dizisine almak için şunları yaparsınız:

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

ÇIKTI

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

Ve sonra kabuk dizinizde.

Onları kabuk dizisine alırsanız, ihtiyacınız bile yoktur printf:

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

ÇIKTI

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

Bu arada, seqve printfbirbirleri için yapılmış. Örneğin bir dizeyi 1000 kez tekrarlamak istersem?

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

ÇIKTI

a string

... 999 a stringsatır sonra ...

a string

Veya...

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

ÇIKTI

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

39 kez komut vermek istiyorum?

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

ÇIKTI

run 1

... 38 runsatır sonra ...

run 39

1

shufÇıktıyı rastgele seçmek için komutu kullanabilirsiniz , örn.

%> 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 olarak, ile arasındaki ondalık tam sayıların karıştırılmış bir listesini oluşturmak miniçin 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]
}'

Birçok awk uygulamasında, bu komutu aynı saniye içinde iki kez çalıştırmanın aynı sonucu üreteceğine dikkat edin ( srand()mevcut zamana göre sözde rasgele üreteci tohumlar olarak ).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.