使用$ RANDOM时,我的脚本会产生相同的输出


8

我试图打印一个随机n字母词,n从命令行本身输入,但是由于某种原因,每次使用相同的值时,我的脚本都会给我相同的答案n

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

我称我的脚本为:

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

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

var3.sh我的脚本的名称在哪里,我要随机打印的单词的长度为5。

如何获得一个真正随机的单词?


3
$RANDOM对于大多数n值,它很可能大于n个字母的单词(对我来说,n = 3 的时间是95.7%)。
Michael Homer

您是否要完全打印一个随机单词,即使它不是单词或从dict随机打印它?
iZodiac

如果您的任务与安全性有关(例如,创建密码),则应使用为该任务制造的工具。否则,可以使用shufsort -R按照答案中的建议进行操作。您也可以使用$RANDOM,但使用更高级的方式。所有这些工具都会产生可以预测的结果(它们并不是真正随机的),但是它们对于许多目的而言都是快速且足够好的。
sudodus

1
也许他们使用这种方法(强制性XKCD参考)
molnarm

Answers:


20

没有。但是$ RANDOM返回大数字(0到32767之间),尤其是对于长度有限的单词,它显示出相同的结果,因为该head部分可能返回grep的所有结果(对于3,我的仅有819个匹配项/usr/share/dict/words)。

更好的解决方案可能是改组结果:

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

where -R表示--random-sort(GNU sort扩展)。


16
为什么tail呢 这在OP的脚本中是有道理的,但是由于您要改组,因此您也可以使用head,然后sort应该能够检测到折断的管道,而不必打乱其余的行。
彼得·泰勒

@PeterTaylor可能是一个很好的提示。使用尾巴只是我的一种习惯...最后,我可能更喜欢使用shuf -n1,这少了一个烟斗...
JakubLucký18年

19

一种打印任意num- letter单词的简单方法是shuf

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

shuf命令输出输入的随机排列,并且-n1标志告诉它仅输出此结果中的第一项。


3
grep -Ex ".{$num}"。或者awk 'length == n' n="$num"'
斯特凡Chazelas

5

正如其他人指出的那样,您的代码的主要问题是,与$RANDOM某个长度的字数相比,该值通常要大得多。

awk仅使用:

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

程序从给定文件中读取一定长度的所有行。这些存储在数组中words

最后,从该数组中选择一个随机元素并进行打印。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.