繁体   English   中英

Bash脚本读取文本文件中的随机行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM