在Unix命令行中从文件中读取随机行的简单方法是什么?

在Unix命令行中从文件中读取随机行的简单方法是什么?

你可以使用shuf

 shuf -n 1 $FILE 

还有一个叫做rl的工具。 在Debian中,它在randomize-lines包中,它完全符合你的要求,尽pipe在所有发行版中都不可用。 在它的主页上,它实际上build议使用shuf (它在创build时不存在,我相信)。 shuf是GNU coreutils的一部分, rl不是。

 rl -c 1 $FILE 

另一种select:

 head -$((${RANDOM} % `wc -l < file` + 1)) file | tail -1 
 sort --random-sort $FILE | head -n 1 

(我更喜欢上面的shuf方法 – 虽然我甚至不知道存在,但我从来没有发现这个工具)

perlfaq5:如何从文件中select一个随机行? 下面是Camel Book的油藏采样algorithm:

 $ perl -e 'srand; rand($.) < 1 && ($line = $_) while <>; print $line;' file 

在阅读整个文件时,这在空间上具有显着的优势。您可以在Donald E. Knuth的“计算机编程艺术”第2卷第3.4.2节中find这种方法的certificate。

使用bash脚本:

 #!/bin/bash # replace with file to read FILE=tmp.txt # count number of lines NUM=$(wc - l < ${FILE}) # generate random number in range 0-NUM let X=${RANDOM} % ${NUM} + 1 # extract X-th line sed -n ${X}p ${FILE} 

这很简单。

 cat file.txt | shuf -n 1 

当然这比“shuf -n 1 file.txt”慢了一点。

单一的bash行:

 sed -n $((1+$RANDOM%`wc -l test.txt | cut -f 1 -d ' '`))p test.txt 

小问题:重复的文件名。

这是一个简单的Python脚本,可以完成这个工作:

 import random, sys lines = open(sys.argv[1]).readlines() print(lines[random.randrange(len(lines))]) 

用法:

 python randline.py file_to_get_random_line_from 

另一种使用' awk '

 awk NR==$((${RANDOM} % `wc -l < file.name` + 1)) file.name 

一种也适用于MacOSX的解决scheme,也适用于Linux(?):

 N=5 awk 'NR==FNR {lineN[$1]; next}(FNR in lineN)' <(jot -r $N 1 $(wc -l < $file)) $file 

哪里:

  • N是你想要的随机线的数量

  • NR==FNR {lineN[$1]; next}(FNR in lineN) file1 file2 NR==FNR {lineN[$1]; next}(FNR in lineN) file1 file2 – >保存写入file1行号,然后在file2打印相应的行

  • jot -r $N 1 $(wc -l < $file) – >用范围(1, number_of_line_in_file)随机抽取N数字( -r )。 过程replace<()将使它看起来像解释器的文件,所以在前面的例子中是file1

如果仅使用vanilla sed和awk,而不使用$ RANDOM,则从名为FILENAME的文件中伪随机地select单行的简单,节省空间和相当快的“单行”如下所示:

 sed -n $(awk 'END {srand(); r=rand()*NR; if (r<NR) {sub(/\..*/,"",r); r++;}; print r}' FILENAME)p FILENAME 

(即使FILENAME为空,在这种情况下也不会发射线。

 #!/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]} 

这是我发现,因为我的Mac OS不使用所有简单的答案。 我使用jot命令来生成一个数字,因为在我的testing中$ RANDOMvariables的解决scheme似乎不是非常随机的。 在testing我的解决scheme时,我在输出中提供的解决scheme有很大的差异。

  RANDOM1=`jot -r 1 1 235886` #range of jot ( 1 235886 ) found from earlier wc -w /usr/share/dict/web2 echo $RANDOM1 head -n $RANDOM1 /usr/share/dict/web2 | tail -n 1 

variables的回显是获得生成的随机数的视觉效果。