我有一个 shell 脚本来运行多次 .c 程序(“switch”),它允许 3 个输入参数。我想运行该程序 4 次,传递值{4,16,32,64}
和参数
{0.1,0.2,.3,.4,.5,.55,.575,.6,.625,.65,.7,.75,.8,.9}
,构建平均值和置信区间表。脚本如下
#!/bin/bash
if [ -e salida.txt ]; then
# echo "File exists"
rm salida.txt
fi
touch salida.txt
touch sal1.txt
touch sal2.txt
touch sal3.txt
touch sal4.txt
touch salida.txt
num=1000000
stud=3.182
for j in {0.1,0.2,.3,.4,.5,.55,.575,.6,.625,.65,.7,.75,.8,.9}
do
rm sal1.txt sal2.txt sal3.txt sal4.txt
for i in {4,16,32,64}
do
margen=0
sum=0
avg=0
for k in {1..4}
do
a$k=$((`./switch -N$i -r$j -n$num`))
sum=$((sum + a$k))
done
avg=$((sum/4))
dvt=0
for k in {1..4}
do
dvt=$((dvt + (a$k - $avg)*(a$k - $avg)))
done
dvt=$((dvt /3))
dvt=$((echo `sqrt($dvt) | bc -l`))
margen=$((dvt*$stud/2))
echo $avg $margen >> sal$i.txt
done
join sal1.txt sal2.txt sal3.txt sal4.txt >> salida.txt
done
尽管如此,第 27 行还是给了我错误
a$k=$((`./switch -N$i -r$j -n$num`))
和线条
dvt=$((echo `sqrt($dvt) | bc -l`))
margen=$((dvt*$stud/2))
我究竟做错了什么?
答案1
您确定的前两行用于 执行命令并捕获其输出。应该是这样。您使用 来 评估数学表达式是正确的。$((command))
$(command)
$((expression))
另外,平方根线应该是
dvt=$(echo "sqrt($dvt)" | bc -l)
而不是
dvt=$((echo `sqrt($dvt) | bc -l`))
甚至
dvt=$(echo `sqrt($dvt) | bc -l`)
该命令的问题margen=
可能是您将浮点数作为表达式的项之一传递给它。
答案2
我会将 的设置重构a$k
为关联数组,如下所示:
declare -a a
for k in {1..4}
do
a[$k]=$((`./switch -N$i -r$j -n$num`))
sum=$((sum + a[$k]))
done
这将允许a
在用上面for
循环中的值填充到代码中其他循环中的值后可以访问该数组。
最后一个for
循环中的这一行也需要像这样进行调整:
dvt=$((dvt + (a[$k] - $avg)*(a[$k] - $avg)))
与 $((..)) 一起浮动
我不相信你可以使用$((...))
符号添加浮点数。至少当我尝试时,它不起作用:
$ echo $((0.10 + .20))
bash: 0.10 + .20: syntax error: invalid arithmetic operator (error token is ".10 + .20")
要使用浮点数作为标记来执行这些操作,您需要使用bc
或可以执行这些操作的计算器。
$ echo "0.10 + .20" | bc
.30