我需要以特定格式生成随机数作为测试数据。例如,给定数字“n”我需要产生“n”个随机数并将它们写入文件中。该文件每行最多包含3个数字。这就是我所拥有的:
#!/bin/bash
m=$1
output=$2
for ((i=1; i<= m; i++)) do
echo $((RANDOM % 29+2)) >> $output
done
输出数字为:
1
2
24
21
10
14
我想要的是:
1 2 24
21 10 14
感谢您的帮助!
答案 0 :(得分:3)
将输出管道传输到一次读取3行的命令:
for ((i=1; i<= m; i++)) do
echo $((RANDOM % 29+2))
done | sed -e '$!N;$!N;s/\n/ /g' >> $output
答案 1 :(得分:3)
Pure bash(写成函数而不是脚本文件)
randx3() {
local d=$' \n'
local i
for ((i=0;i<$(($1 - 1));++i)); do
printf "%d%c" $((RANDOM%29 + 2)) "${d:$((i%3)):1}"
done
printf "%d\n" $((RANDOM%29 + 2))
}
请注意,它不带文件参数;而是输出到stdout,所以你会像这样使用它:
randx3 11 > /path/to/output
这种风格通常更灵活。
这是一个不太常见的问题,它允许您选择换行的频率:
randx() {
local i
local m=$1
local c=${2:-3}
for ((i=1;i<=m;++i)); do
if ((i%c && i<m)); then
printf "%d " $((RANDOM%29 + 2))
else
printf "%d\n" $((RANDOM%29 + 2))
fi
done
}
将其称为randx 11
或randx 11 7
(第二个参数默认为3)。
答案 2 :(得分:1)
这是paste
的目的:
$ for i in {0..10}; do echo $RANDOM; done | paste -d' ' - - -
14567 3240 16354
17457 25616 12772
3912 7490 12206
7342 10554
另一种方法是在数组中构建值,然后使用printf。
m=$1
output=$2
vals=()
while (( m-- )); do
vals+=( $((RANDOM % 29+2)) )
done
printf '%d %d %d\n' "${vals[@]}" > "$output"
答案 3 :(得分:1)
m=$1
output=$2
out=()
for ((i=1;i<=m;i++));do
out+=($((RANDOM%29+2)))
[ $((i%3)) -eq 0 ] && echo ${out[*]} >>$output && out=()
done
[ "$out" ] && echo ${out[*]} >>$output
RANDOM%29
这种在2到30之间呈现随机的方式不是公平:
当$RANDOM
给出0
和32767
之间的数字时,有:
for ((i=0;i<32768;i++)) ;do
((RL[$((i%29+2))]++))
done
for ((i=0;i<32;i++));do
printf "%3d %5d\n" $i ${RL[i]}
done | column
0 0 7 1130 14 1130 21 1130 28 1130
1 0 8 1130 15 1130 22 1130 29 1129
2 1130 9 1130 16 1130 23 1130 30 1129
3 1130 10 1130 17 1130 24 1130 31 0
4 1130 11 1130 18 1130 25 1130
5 1130 12 1130 19 1130 26 1130
6 1130 13 1130 20 1130 27 1130
因此有1130个机会获得2到28之间的数字,但仅 1129获得29或30的机会。
为防止出现这种情况,您必须删除不需要的结果:
random2to30() {
local _random=32
while [ $_random -gt 28 ] ;do
_random=$((RANDOM & 2#11111)) # return 5 bit random 0 to 31
done
printf -v $1 "%d" $((2+_random)) # Assign variable to prevent forks
}
证据:
tstr2to30() {
unset $1
local _random=32
while [ $_random -gt 28 ] && read _random ;do
_random=$((_random& 2#11111))
done
[ "$_random" ] && printf -v $1 "%d" $((2+_random))
}
unset RL
while tstr2to30 MyRandom && [ "$MyRandom" ] ;do
((RL[MyRandom]++))
done < <(seq 0 32767)
for ((i=0;i<32;i++));do
printf "%3d %5d\n" $i ${RL[i]}
done | column
提供:
0 0 7 1024 14 1024 21 1024 28 1024
1 0 8 1024 15 1024 22 1024 29 1024
2 1024 9 1024 16 1024 23 1024 30 1024
3 1024 10 1024 17 1024 24 1024 31 0
4 1024 11 1024 18 1024 25 1024
5 1024 12 1024 19 1024 26 1024
6 1024 13 1024 20 1024 27 1024
所有值确实获得完全相同(1024)的机会。
所以脚本变成了(别忘了bash的shebang!):
#!/bin/bash
m=${1:-11} # default to 11 values
output=${2:-/dev/stdout} # default to STDOUT
c=${3:-3} # default to 3 values by lines
random2to30() {
local _random=32
while [ $_random -gt 28 ] ;do
_random=$((RANDOM & 2#11111)) # return 5 bit random 0 to 31
done
printf -v $1 "%d" $((2+_random)) # Assign variable to prevent forks
}
out=()
for ((i=1;i<=m;i++));do
random2to30 MyRandom
out+=($MyRandom)
[ $((i%c)) -eq 0 ] && echo ${out[*]} >>"$output" && out=()
done
[ "$out" ] && echo ${out[*]} >>"$output"
答案 4 :(得分:0)
此awk将在每第3行或空格后插入换行符:
for ((i=1; i<= m; i++)); do
echo $((RANDOM % 29+2))
done | awk '{printf "%s%c", $1, (NR % 3) ? " " : "\n"}' >> $output
答案 5 :(得分:0)
另一种方法:
eval echo {1..$m} | xargs -n3 echo $((RANDOM % 29+2)) > $output