[英]Bash script reading random lines in a text file
我有一個單行bash腳本,可以讀取文本文件中的隨機行:
#!/bin/bash
shuf -n 1 excuses.txt
當我調用腳本時,它給了我一個隨機的單行代碼,但是我注意到我在腳本中使用的命令實際上並不是那么隨機,當我多次運行該腳本時,我可能會看到同一行被讀取(即使這是隨機的)。 我的問題是:是否有另一種方式可以隨機打印一行可能比我的代碼中隨機得多的文本? 請注意,我有1,000行可以從此文本文件中讀取。
編輯:這是我使用shuf
隨機化文本文件時的結果:
[root@ftpserver bofh] ./bastardScript.sh
Atilla the Hub
[root@ftpserver bofh] ./bastardScript.sh
kernel panic: write-only-memory (/dev/wom0) capacity exceeded.
[root@ftpserver bofh] ./bastardScript.sh
We had to turn off that service to comply with the CDA Bill.
[root@ftpserver bofh] ./bastardScript.sh
YOU HAVE AN I/O ERROR -> Incompetent Operator error
[root@ftpserver bofh] ./bastardScript.sh
Change in Earth's rotational speed
[root@ftpserver bofh] ./bastardScript.sh
Atilla the Hub
如您所見,在我使用腳本的時間內(大約6到10次):
[root@ftpserver bofh] ./bastardScript.sh
Atilla the Hub
過來。 我想看看它是否可以變得比現在更隨機。
#!/bin/bash
cat excuses.txt | sort --random-sort | head -n 1
如果要確保shuf
使用的是高熵源:
shuf -n 1 --random-source=/dev/random <excuses.txt
就是說,聽起來您真正想要的是不要兩次看到相同的借口(直到它們全部被消耗掉)。 在這種情況下,我考慮將文件改組一次,存儲一個計數器,然后依次顯示每一行。
# In Bash 3 or earlier, you'll need to hardcode a FD number here.
exec {lock_fd}>excuses.count
flock -x "$lock_fd"
[[ -e excuses.shuffled ]] || {
shuf <excuses.txt >excuses.shuffled || exit
echo 1 >excuses.count
}
[[ -s excuses.shuffled ]] || exit
counter=$(<excuses.count)
line=$(sed -n "${counter} p" <excuses.shuffled)
if [[ $line ]]; then
echo "$line"
echo "$((counter + 1))" >excuses.count
else
# ran out of lines; delete files and restart this script to reshuffle
rm -- excuses.shuffled # clear our now-used shuffle
exec {lock_fd}<&- # release the lock
exec "$0" "$@" # restart the script
fi
您想要的顯然不是隨機的。
如果不想重復舊的行,則需要某種方式來記住以前的結果。
我要做的是將整個文件混洗並將其存儲在某個位置。 然后,每次調用該腳本時,抓住最后一行並將其刪除。 一旦檢測到文件為空,就必須再次洗牌。
如果您擔心並發,則需要適當的文件鎖定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.