从文本文件中获取随机选择的行的百分比

时间:2017-10-12 15:33:20

标签: bash shell

我有一个包含数千行的文本文件(bigfile.txt)。我想制作一个较小的文本文件,其中1%的行是随机选择的。我尝试了以下

output=$(wc -l bigfile.txt)
ds1=$(0.01*output)
sort -r bigfile.txt|shuf|head -n ds1 

它给出以下错误: head:行数无效:'ds1'

我不知道出了什么问题。

2 个答案:

答案 0 :(得分:4)

即使您使用bash脚本解决了问题,也无法进行浮点运算。您需要Awk之类的外部工具,我将其用作

randomCount=$(awk 'END{print int((NR==0)?0:(NR/100))}' bigfile.txt)
(( randomCount )) && sort -r file | shuf | head -n "$randomCount"

E.g。使用下面的循环编写带有221行的文件并尝试获取随机行,

tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
for i in {1..221}; do echo $i; done >> "$tmpfile"
randomCount=$(awk 'END{print int((NR==0)?0:(NR/100))}' "$tmpfile")

如果我打印计数,它将返回一个整数2并在下一个命令

上使用它
sort -r "$tmpfile" | shuf | head -n "$randomCount"
86
126

答案 1 :(得分:2)

为文件的每一行掷骰子(rand()),并获得01之间的数字。如果模具显示小于0.01

,则打印该行
awk 'rand()<0.01' bigFile

快速测试 - 生成100,000,000行并计算通过次数:

seq 1 100000000 | awk 'rand()<0.01' | wc -l
999308

非常接近1%。

如果您想要订单随机和选择,您可以在之后通过shuf传递:

seq 1 100000000 | awk 'rand()<0.01' | shuf

关于评论中提出的效率问题,这个解决方案在我的iMac上需要24秒,100,000,000行:

time { seq 1 100000000 | awk 'rand()<0.01' > /dev/null; }

real    0m23.738s
user    0m31.787s
sys     0m0.490s

在这里工作的唯一其他解决方案,基于OP的原始代码,需要13分19秒。