atribui a saída de um programa c a uma variável shell: token error

2

Eu tenho um shell script para executar várias vezes um programa .c ('switch') que admite 3 parâmetros de entrada. Eu quero correr 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 script é 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  

No entanto 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?

    
por Pablo 10.10.2014 / 19:13

2 respostas

1

As duas primeiras linhas que você identificou estão usando $((command)) para executar um comando e capturar sua saída. Isso deve ser $(command) . Seus usos de $((expression)) para avaliar uma expressão matemática estão corretas.

Além disso, a linha de raiz quadrada deve ser

dvt=$(echo "sqrt($dvt)" | bc -l)

em vez de

dvt=$((echo 'sqrt($dvt) | bc -l'))

ou até mesmo

dvt=$(echo 'sqrt($dvt) | bc -l')

O problema com o comando margen= pode ser que você esteja passando um float como um dos termos da expressão.

    
por 10.10.2014 / 20:57
1

Eu reestruturaria a configuração de a$k para um array associativo como este:

    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 a matriz, a , estivesse acessível após ser preenchida com valores do loop for acima para outros loops mais abaixo em seu código.

Esta linha mais abaixo no último loop for também precisa ser ajustada da seguinte forma:

        dvt=$((dvt + (a[$k] - $avg)*(a[$k] - $avg)))  

Flutua com $ ((..))

Eu não acredito que você possa adicionar floats usando a notação $((...)) . Pelo menos quando eu 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 floats como tokens você precisará usar bc ou uma calculadora que possa executá-las.

$ echo "0.10 + .20" | bc
.30
    
por 10.10.2014 / 19:46