在Unix命令行中从文件中读取随机行的简单方法是什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Unix命令行中从文件中读取随机行的简单方法是什么?相关的知识,希望对你有一定的参考价值。
在Unix命令行中从文件中读取随机行的简单方法是什么?
你可以使用shuf
:
shuf -n 1 $FILE
还有一个名为rl
的实用程序。在Debian中,它在randomize-lines
包中完全符合您的要求,但并非在所有发行版中都可用。在它的主页上,它实际上建议使用shuf
(我相信它在创建时不存在)。 shuf
是GNU coreutils的一部分,rl
不是。
rl -c 1 $FILE
一个也适用于MacOSX的解决方案,也适用于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
- >保存用file1
写的行号,然后在file2
中打印相应的行jot -r $N 1 $(wc -l < $file)
- >用N
在-r
范围内随机抽取(1, number_of_line_in_file)
数字(jot
)。进程替换<()
将使它看起来像解释器的文件,所以在前面的例子中file1
。
#!/bin/bash
IFS=$'
' 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命令生成一个数字,因为$ RANDOM变量解决方案似乎在我的测试中不是很随机。在测试我的解决方案时,我在输出中提供的解决方案中存在很大差异。
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
变量的回声是获得生成的随机数的视觉效果。
仅使用vanilla 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
(可以根据归纳给出一个简单的正确证明。)
Caveat about rand()
“在大多数awk实现中,包括gawk,rand()每次运行awk时都会从相同的起始编号或种子开始生成数字。”
- https://www.gnu.org/software/gawk/manual/html_node/Numeric-Functions.html
另一种选择:
head -$((${RANDOM} % `wc -l < file` + 1)) file | tail -1
sort --random-sort $FILE | head -n 1
(我喜欢上面的shuf方法甚至更好 - 我甚至不知道存在,我自己也没有找到这个工具)
这很简单。
cat file.txt | shuf -n 1
当然这只比它自己的“shuf -n 1 file.txt”慢一点。
perlfaq5: How do I select a random line from a file?这是Camel Book中的油藏采样算法:
perl -e 'srand; rand($.) < 1 && ($line = $_) while <>; print $line;' file
这在读取整个文件的空间方面具有显着的优势。您可以在Donald E. Knuth的“计算机编程艺术”第2卷第3.4.2节中找到这种方法的证明。
使用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}
单击线:
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
以上是关于在Unix命令行中从文件中读取随机行的简单方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章