我有一个包含数千行的文本文件(bigfile.txt)。我想制作一个较小的文本文件,其中1%的行是随机选择的。我尝试了以下
output=$(wc -l bigfile.txt)
ds1=$(0.01*output)
sort -r bigfile.txt|shuf|head -n ds1
它给出以下错误: head:行数无效:'ds1'
我不知道出了什么问题。
答案 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()
),并获得0
和1
之间的数字。如果模具显示小于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秒。