在shell脚本中从文件中读取随机行有什么简单的方法?
当前回答
sort --random-sort $FILE | head -n 1
(我更喜欢上面的shiff方法——我甚至不知道它的存在,我自己也永远不会找到这个工具)
其他回答
这很简单。
cat file.txt | shuf -n 1
当然,这只是比“shuf -n 1 file.txt”本身稍微慢一点。
只使用普通sed和awk,不使用$RANDOM,一个简单、节省空间和合理快速的“一行程序”可以从文件名FILENAME中伪随机地选择一行,如下所示:
sed -n $(awk 'END {srand(); r=rand()*NR; if (r<NR) {sub(/\..*/,"",r); r++;}; print r}' FILENAME)p FILENAME
(即使FILENAME为空也能工作,在这种情况下不会触发任何行。)
这种方法的一个可能的优点是它只调用rand()一次。
正如@AdamKatz在评论中指出的,另一种可能是为每一行调用rand():
awk 'rand() * NR < 1 { line = $0 } END { print line }' FILENAME
(基于归纳法可以给出简单的正确性证明。)
关于rand的警告()
在大多数awk实现中,包括gawk, rand()每次运行awk时都从相同的起始数字或种子开始生成数字。
——https://www.gnu.org/software/gawk/manual/html_node/Numeric-Functions.html
#!/bin/bash
IFS=$'\n' wordsArray=($(<$1))
numWords=${#wordsArray[@]}
sizeOfNumWords=${#numWords}
while [ True ]
do
for ((i=0; i<$sizeOfNumWords; i++))
do
let ranNumArray[$i]=$(( ( $RANDOM % 10 ) + 1 ))-1
ranNumStr="$ranNumStr${ranNumArray[$i]}"
done
if [ $ranNumStr -le $numWords ]
then
break
fi
ranNumStr=""
done
noLeadZeroStr=$((10#$ranNumStr))
echo ${wordsArray[$noLeadZeroStr]}
sort --random-sort $FILE | head -n 1
(我更喜欢上面的shiff方法——我甚至不知道它的存在,我自己也永远不会找到这个工具)
单个bash行:
sed -n $((1+$RANDOM%`wc -l test.txt | cut -f 1 -d ' '`))p test.txt
小问题:重复的文件名。