Tengo un script de shell para ejecutar varias veces un programa .c ('switch') que admite 3 parámetros de entrada. Quiero ejecutar el programa 4 veces pasando valores {4,16,32,64}
y, para los parámetros
{0.1,0.2,.3,.4,.5,.55,.575,.6,.625,.65,.7,.75,.8,.9}
, crear una tabla de promedio e intervalo de confianza. El guión es el siguiente.
#!/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
Sin embargo me está dando error en la línea 27.
a$k=$((`./switch -N$i -r$j -n$num`))
y lineas
dvt=$((echo `sqrt($dvt) | bc -l`))
margen=$((dvt*$stud/2))
¿Qué estoy haciendo mal?
Respuesta1
Las dos primeras líneas que identificó se utilizan para ejecutar un comando y capturar su resultado. Eso debería ser . Tus usos de para evaluar una expresión matemática son correctos.$((command))
$(command)
$((expression))
Además, la línea de la raíz cuadrada debe ser
dvt=$(echo "sqrt($dvt)" | bc -l)
en vez de
dvt=$((echo `sqrt($dvt) | bc -l`))
o incluso
dvt=$(echo `sqrt($dvt) | bc -l`)
El problema con el margen=
comando puede ser que le estás pasando un flotante como uno de los términos de la expresión.
Respuesta2
Reestructuraría la configuración de a$k
a una matriz asociativa como esta:
declare -a a
for k in {1..4}
do
a[$k]=$((`./switch -N$i -r$j -n$num`))
sum=$((sum + a[$k]))
done
Esto permitiría que a
se pueda acceder a la matriz después de que se complete con valores del for
bucle anterior a otros bucles más abajo en su código.
Esta línea más abajo en el último for
bucle también debe ajustarse de la siguiente manera:
dvt=$((dvt + (a[$k] - $avg)*(a[$k] - $avg)))
Flota con $((..))
No creo que puedas agregar flotantes usando la $((...))
notación. Al menos cuando lo probé no funcionó:
$ echo $((0.10 + .20))
bash: 0.10 + .20: syntax error: invalid arithmetic operator (error token is ".10 + .20")
Para realizar esas operaciones con flotadores como tokens, necesitará usar bc
una calculadora que pueda realizarlas.
$ echo "0.10 + .20" | bc
.30