具有:
mapfile -t words < <( head -10000 /usr/share/dict/words)
echo "${#words[@]}" #10000
r=$(( $RANDOM % ${#words[@]} ))
echo "$r ${words[$r]}"
这段代码从包含1万个单词的数组中随机选择一个单词。
但是,如果数组更大(例如,整个文件有超过200k个单词),它会停止工作,因为$RANDOM
只能到达32767。来自man bash
的信息如下:
每次引用该参数时,都会生成0到32767之间的随机整数。
mapfile -t words < /usr/share/dict/words
echo "${#words[@]}" # 235886
r=$(( $RANDOM % ${#words[@]} )) #how to change this?
echo "$r ${words[$r]}"
不想使用像perl -plE 's/.*/int(rand()*$_)/e'
这样的Perl代码,因为并非每个系统都安装了Perl。寻找最简单的解决方案-也不关心真正的随机性-这不是用于加密技术。:)
sed -n "${num}p" file
更好吗?比如运行一个读取文件的外部程序?mapfile是内置的,我可以简单地清除数组...还是我漏掉了什么? - cajwinesed
,就像你提到的那样。mapfile
将至少消耗与文件大小相同的进程内存(尽管是临时的)。sed
会一次消耗一行的内存。你是否接受这种方式取决于你自己。 - slimwc -l
来获取单词数量,然后第二次需要运行sed
,因此我使用了mapfile
。不过,我会做一些测试并看看效果。感谢您的建议。 :) - cajwineexpr
来进行数学计算,当shell已经完全能够胜任呢:“big_random=$((32768*RANDOM+RANDOM))
”。是的,这个乘数应该是32768(而不是32767)。或者,如果你想避免乘法,可以使用更快的位移方式:"big_random=$(((RANDOM<<15)+RANDOM))
"。 - user8017719