Bash: incrementa uma variável em um loop while?

0

Eu tenho um script bash que para cada arquivo em um conjunto, usa cada linha no arquivo para uma string. Em seguida, ele divide a linha em vírgulas, converte o sétimo elemento em float e incrementa um total em execução por esse valor.

Parece assim:

for filename in data*.CSV; do
   echo $filename
   ACTUAL_COST=0
   grep '040302010' $filename | while read -r line ; do
       IFS=',' read -a array <<< "$line"
       ACTUAL_COST=$(echo "$ACTUAL_COST + ${array[7]}" | bc)
       echo $ACTUAL_COST
   done
   echo $ACTUAL_COST
done

Mas o problema que estou tendo é que isso produz uma saída assim:

53.4
72.2
109.1
0

O último valor é sempre 0. Depois de pesquisar um pouco, acho que isso ocorre porque o loop while está sendo executado em uma subshell e, portanto, a variável externa não é alterada.

Eu entendo que provavelmente preciso executar o loop interno em uma função.

    
por Richard 29.06.2015 / 15:36

3 respostas

0

Pode ser útil introduzir outra substituição de comando, com a lógica do loop principal definida em uma função:

sum_cost() {
   sum=0
   while read -r line ; do
       IFS=',' read -a array <<< "$line"
       sum=$(echo "$sum + ${array[7]}" | bc)
   done
   echo $sum
}

for filename in data*.CSV; do
   echo $filename
   ACTUAL_COST=$(grep '040302010' $filename | sum_cost)
   echo $ACTUAL_COST
done
    
por 29.06.2015 / 16:19
2

Não é assim que você faz o script de shell . Você está executando vários comandos em sequência para cada linha dos arquivos!

Aqui você quer algo como:

awk -F, '/040302010/ {actual_cost += $7}
         ENDFILE {print FILENAME ":", +actual_cost; actual_cost=0}
        ' data*.CSV

(assumindo o GNU awk).

Isso é um um comando no total para todos os seus arquivos.

    
por 29.06.2015 / 17:08
0

Para evitar o subshell, você pode usar o seguinte:

while read -r line
do
    your_stuff
done < <(grep '040302010' $filename')

Dessa forma, você é capaz de preencher o (s) resultado (s) na variável.

    
por 29.06.2015 / 15:41