Kịch bản của tôi tạo ra cùng một đầu ra khi sử dụng $ RANDOM


8

Tôi đang cố gắng in một ntừ chữ ngẫu nhiên , trong đó tôi nhập ntừ chính dòng lệnh, nhưng vì một số lý do, tập lệnh của tôi sẽ cho tôi cùng một câu trả lời mỗi khi sử dụng cùng một giá trị n.

#!/bin/bash                                                                                                                                       
num=$1
egrep "^.{$num}$" /usr/share/dict/words | head -n $RANDOM| tail -n 1

Tôi đang gọi kịch bản của mình như sau:

$ bash var3.sh 5
étude             # always the same output when using 5 

$ bash var3.sh 3
zoo               # always the same output when using 3

trong đó var3.shtên của kịch bản của tôi và 5 là độ dài của từ tôi muốn in ngẫu nhiên.

Làm thế nào để tôi có được nó để in một từ thực sự ngẫu nhiên?


3
$RANDOMkhá có khả năng lớn hơn số lượng từ n -letter cho hầu hết các giá trị của n (95,7% thời gian cho n = 3 đối với tôi).
Michael Homer

Bạn đang tìm cách in một từ ngẫu nhiên hoàn toàn, ngay cả khi đó không phải là một từ hoặc in ngẫu nhiên từ chính tả?
iZ Zodiac

Nếu tác vụ của bạn liên quan đến bảo mật (ví dụ để tạo mật khẩu), bạn nên sử dụng một công cụ được tạo cho tác vụ đó. Mặt khác, có thể sử dụng shufhoặc sort -Rnhư được đề xuất trong các câu trả lời. Bạn cũng có thể sử dụng $RANDOM, nhưng theo một cách tiên tiến hơn. Tất cả các công cụ này tạo ra kết quả có thể dự đoán (chúng không thực sự ngẫu nhiên), nhưng chúng nhanh và đủ tốt cho nhiều mục đích.
sudodus

1
Có thể họ sử dụng phương pháp này (tham chiếu XKCD bắt buộc)
molnarm

Câu trả lời:


20

Nó không. Nhưng $ RANDOM trả về số lớn (từ 0 đến 32767), đặc biệt đối với các từ có độ dài giới hạn, cho thấy kết quả tương tự, vì headphần này có thể trả về tất cả các kết quả của grep (trong 3, chỉ có 819 kết quả khớp với tôi /usr/share/dict/words).

Giải pháp tốt hơn có thể là xáo trộn kết quả:

egrep "^.{$num}$" /usr/share/dict/words | sort -R | tail -n 1

trong đó -Rcó nghĩa là --random-sort(một sortphần mở rộng GNU ).


16
Tại sao tail? Điều đó có ý nghĩa trong kịch bản của OP, nhưng vì bạn đang xáo trộn nên bạn cũng có thể sử dụng head, và sau đó sortsẽ có thể phát hiện đường ống bị hỏng và không bận tâm đến việc xáo trộn các dòng còn lại.
Peter Taylor

@PeterTaylor có lẽ là một mẹo hay. Sử dụng đuôi chỉ là thói quen của tôi ... Cuối cùng, có lẽ tôi thích nhiều hơn shuf -n1, đó là một ống ít hơn ...
Jakub Lucký

19

Một phương pháp đơn giản để in một từ chữ số tùy ý sử dụng shuf:

egrep "^.{$num}$" /usr/share/dict | shuf -n1

Các shuflệnh xuất ra một hoán vị ngẫu nhiên của các đầu vào, và -n1cờ nói với nó để chỉ ra mục đầu tiên từ kết quả này.


3
hoặc grep -Ex ".{$num}". Hoặc awk 'length == n' n="$num"'.
Stéphane Chazelas

5

Như những người khác đã chỉ ra, vấn đề chính với mã của bạn là $RANDOMthường xuyên hơn không phải là một giá trị lớn hơn nhiều so với số lượng từ có độ dài nhất định.

awkChỉ sử dụng :

$ awk -v len="$num" 'length == len { word[i++]=$0 }
                     END { print word[int(i*rand())] }' /usr/share/dict/words
Bosniac

Chương trình đọc trong tất cả các dòng từ tệp đã cho có độ dài nhất định. Chúng được lưu trữ trong mảng words.

Cuối cùng, một yếu tố ngẫu nhiên từ mảng này được chọn và in.

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.