Làm thế nào để ngẫu nhiên đầu ra từ seq?


11

Tôi biết tôi có thể sử dụng seqđể tạo danh sách các số ngẫu nhiên: 1, 2, 3, 4 ...

Tôi muốn nhận các số đó theo thứ tự ngẫu nhiên như 3, 1, 4, 2 ...

Tôi biết tôi có thể sử dụng shufđể xáo trộn các dòng của một tập tin. Vì vậy, tôi có thể sử dụng seqđể ghi số ngẫu nhiên vào một tệp và sau đó sử dụng shufđể xáo trộn chúng - hoặc viết một số loại hàm xáo trộn. Nhưng điều này có vẻ phức tạp không cần thiết. Có cách nào đơn giản hơn để ngẫu nhiên các mục trong một mảng bằng một lệnh không?

Câu trả lời:


16

Bạn chỉ có thể dẫn đầu ra shuf.

$ seq 100 | shuf

Thí dụ

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

Nếu bạn muốn đầu ra nằm ngang thì hãy đặt nó vào 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 

Bạn muốn nó với dấu phẩy ở giữa? Thay đổi dấu phân cách thành paste:

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

Nhưng bạn phải định dạng bằng cách nào đó để có được chúng trên một dòng bằng dấu phẩy. echo $(seq 10 | shuf)đến gần nhưng không làm dấu phẩy.
mikeerv

Nó nằm ngang trước paste...
mikeerv

@mikeerv - Thay đổi nó xung quanh.
slm

Vâng. Có bạn đi. Tôi không biết pasteđã làm điều đó. Cảm ơn vì đã dạy cho tôi. Có một upvote.
mikeerv

@mikeerv - yeah đọc qua trang web nhìn vào của tôi, của Stephane hoặc Gilles A đang sử dụng joinpaste. Hai công cụ đó cực kỳ mạnh mẽ.
slm

3

Có cách nào đơn giản hơn để ngẫu nhiên các mục trong một mảng bằng một lệnh không?

Giả sử bạn có một mảng các số nguyên thập phân:

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

Bạn có thể sử dụng printfshufchọn ngẫu nhiên các thành phần của mảng:

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

(ở trên giả định bạn chưa sửa đổi $IFS).


Nếu tất cả những gì bạn cần là số ngẫu nhiên giữa hai số nguyên, giả sử 1020, bạn không cần bất kỳ quy trình bổ sung nào ngoài shufviệc sử dụng -itùy chọn:

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

Trích dẫn từ man shuf:

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

Shucks. Tôi cũng thấy vậy shuf --helpnhưng tôi đã cố gắng sử dụng shuf -i 1 10mà không có sự can thiệp -dash.ồ, làm tốt lắm - có upvote của tôi.
mikeerv

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

Bạn thậm chí không cần một forvòng lặp.

ĐẦU RA

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

Để có được chúng trong một mảng shell bạn làm:

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

ĐẦU RA

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

Và sau đó chúng nằm trong mảng vỏ của bạn.

Nếu bạn nhận được chúng trong mảng shell, bạn thậm chí không cần printf:

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

ĐẦU RA

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

Nhân tiện, seqprintfđược làm cho nhau. Chẳng hạn, nếu tôi muốn lặp lại một chuỗi 1000 lần?

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

ĐẦU RA

a string

... 999 a stringdòng sau ...

a string

Hoặc là...

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

ĐẦU RA

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

Tôi muốn thực thi một lệnh 39 lần?

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

ĐẦU RA

run 1

... 38 rundòng sau ...

run 39

1

Bạn có thể sử dụng shuflệnh để ngẫu nhiên hóa đầu ra, vd

%> 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, để tạo danh sách xáo trộn các số nguyên thập phân từ minđến 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]
}'

Xin lưu ý rằng với nhiều triển khai awk, chạy lệnh đó hai lần trong cùng một giây sẽ tạo ra kết quả tương tự ( srand()giống như trình tạo giả ngẫu nhiên dựa trên thời gian hiện tại).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.