您好我有一个脚本,用于计算服务器返回的一组值的标准偏差。
我可以轻松地检索命令并使用命令构建有效的字符串。
bc <<< "scale=10; sqrt((0+((782636-782030)^2)+((781460-782030)^2)+((782492-782030)^2)+((781704-782030)^2)+((781860-782030)^2))/5)"
我通过迭代数组并将其附加到字符串来创建此命令。
CMD='bc <<< "scale=10; sqrt((0'
for i in "${MEMORY[@]}"; do
CMD=$CMD'+(('$i'-'$MEAN')^2)'
done;
CMD=$CMD')/5)"'
一旦我完成了这个,然后尝试将命令字符串执行到变量
SD=`$CMD`
echo $SD
但是我得到了输出
File <<< is unavailable.
任何想法?
答案 0 :(得分:4)
<<<
需要由shell解析,这在参数扩展之前发生。当您尝试执行
SD=`$CMD`
$CMD
中的字符串未被重新分析,因此<<<
被视为文字字符串,并作为参数传递给bc
。你需要像
BC_EXPRESSION='scale=10; sqrt((0'
for i in "${MEMORY[@]}"; do
BC_EXPRESSION+="+(($i-$MEAN)^2)"
done
BC_EXPRESSION+=')/5)'
SD=$( bc <<< "$BC_EXPRESSION" )
答案 1 :(得分:2)
您应该在字符串中构建bc
命令,然后将此字符串传递给bc
。
如果我理解正确,你有一组数字memory
1 和一个变量mean
,你想要计算memory
的标准差(在哪里,我猜,mean
是memory
)的平均值。
您需要构建(X-mean)^2
形式的字符串:
sum_terms=0
for i in "${memory[@]}"; do
sum_terms+="+(($i)-($mean))^2"
done
此时,字符串sum_terms
包含扩展为类似的字符串:
0+((m1)-(mean))^2+((m2)-(mean))^2+ ... +((mn)-(mean))^2
最后,您希望将其括在括号中,添加sqrt(
并附加/5)
并将其传递给bc
:
bc <<< "sqrt(($sum_terms)/5)"
一体化:
sum_terms=0
for i in "${memory[@]}"; do
sum_terms+="+(($i)-($mean))^2"
done
bc -l <<< "sqrt(($sum_terms)/5)"
请注意,我将$mean
括号括在括号中,以防这是一个负数(否则会与前面的负号冲突) - 当我在它的时候,我也附上了{{括号中的1}}术语。
作为旁注,您还可以使用$i
来计算标准偏差,并以更通用的方式进行:
给定数组E((X-E(X))^2)=E(X^2)-E(X)^2
,计算其标准偏差:
memory
事实上,你真的不需要明确的memory=( 782636 781460 782492 781704 781860 )
sum_mem=0 sum_memsq=0
for i in "${memory[@]}"; do
sum_mem+="+($i)"
sum_memsq+="+($i)^2"
done
mean=$(bc -l <<< "($sum_mem)/${#memory[@]}")
bc -l <<< "sqrt(($sum_memsq)/${#memory[@]}-($mean)^2)"
循环,你可以让for
为你完成工作:
printf
1 让我小写所有变量名,大写变量名被认为是不好的做法
答案 2 :(得分:0)
请尝试:
echo "scale=10; sqrt((0+((782636-782030)^2)+((781460-782030)^2)+((782492-782030)^2)+((781704-782030)^2)+((781860-782030)^2))/5)" | bc -l
即。 echo
您的字符串并将输出传递给bc -l
这将有效