Eu tenho um script de shell para executar várias vezes um programa .c ('switch') que admite 3 parâmetros de entrada. Quero executar o programa 4 vezes passando valores {4,16,32,64}
, e para parâmetros
{0.1,0.2,.3,.4,.5,.55,.575,.6,.625,.65,.7,.75,.8,.9}
, construindo uma tabela de média e intervalo de confiança. O roteiro é o seguinte
#!/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
Mesmo assim está me dando erro na linha 27
a$k=$((`./switch -N$i -r$j -n$num`))
e linhas
dvt=$((echo `sqrt($dvt) | bc -l`))
margen=$((dvt*$stud/2))
O que estou fazendo de errado?
Responder1
As duas primeiras linhas que você identificou são usadas para executar um comando e capturar sua saída. Isso deveria ser . Seus usos para avaliar uma expressão matemática estão corretos.$((command))
$(command)
$((expression))
Além disso, a linha da raiz quadrada deve ser
dvt=$(echo "sqrt($dvt)" | bc -l)
em vez de
dvt=$((echo `sqrt($dvt) | bc -l`))
ou mesmo
dvt=$(echo `sqrt($dvt) | bc -l`)
O problema com o margen=
comando pode ser que você esteja passando um float como um dos termos da expressão.
Responder2
Eu reestruturaria a configuração a$k
para uma matriz associativa 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
Isso permitiria que o array a
ficasse acessível depois de preenchido com valores do for
loop acima para outros loops mais abaixo em seu código.
Esta linha mais abaixo no último for
loop também precisa ser ajustada assim:
dvt=$((dvt + (a[$k] - $avg)*(a[$k] - $avg)))
Flutua com $((..))
Não acredito que você possa adicionar carros alegóricos usando a $((...))
notação. Pelo menos quando tentei, não funcionou:
$ echo $((0.10 + .20))
bash: 0.10 + .20: syntax error: invalid arithmetic operator (error token is ".10 + .20")
Para realizar essas operações com carros alegóricos como tokens, você precisará usar bc
uma calculadora que possa realizá-las.
$ echo "0.10 + .20" | bc
.30