692 votes

Comment puis-je ajouter des nombres dans un script bash

J'ai ce script bash et j'ai eu un problème à la ligne 16. Comment puis-je prendre le résultat précédent de la ligne 15 et l'ajouter à la variable de la ligne 16?

 #!/bin/bash

num=0
metab=0

for ((i=1; i<=2; i++)); do      
    for j in `ls output-$i-*`; do
        echo "$j"

        metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15)
        num= $num + $metab   (line16)
    done
    echo "$num"
 done
 

1187voto

Karoly Horvath Points 45145

Pour les entiers:

  • Utilisez l'expansion arithmétique: $((EXPR))

    num=$((num1 + num2))
    num=$(($num1 + $num2))       # also works
    num=$((num1 + 2 + 3))        # ...
    num=$[num1+num2]             # old, deprecated arithmetic expression syntax
    
  • À l'aide de l'externe expr utilitaire. Notez que cela n'est nécessaire que pour de très vieux systèmes.

    num=`expr $num1 + $num2`     # whitespace for expr is important
    

Pour la virgule flottante:

num=$(echo $num1 + $num2 | bc)   # whitespace for echo is important

Les pièges les plus courants:

  • Lors de la définition d'une variable, vous ne pouvez pas avoir des espaces de chaque côté de l' =, sinon il va forcer le shell pour interpréter le premier mot que le nom de l'application à exécuter (par exemple: num=)

    num= 1 num =2

  • bc et expr s'attendent chaque nombre et l'opérateur comme un argument séparé, de sorte que les espaces sont importants. Ils ne peuvent pas traiter les arguments comme 3+ +4.

    num=`expr $num1+ $num2`

171voto

Steve Prentice Points 7638

Utilisez l'expansion arithmétique $(( )) .

 num=$(( $num + $metab ))
 

Voir http://tldp.org/LDP/abs/html/arithexp.html pour plus d'informations.

33voto

Sorpigal Points 10412

Il y a mille et une façons de le faire. Voici un à l'aide d' dc:

dc <<<"$num1 $num2 + p"

Mais si c'est trop bash-y pour vous (ou de la portabilité des questions), vous pourriez dire

echo $num1 $num2 + p | dc

Mais peut-être que vous êtes une de ces personnes qui pense RPN est dégueulasse et bizarre; ne vous inquiétez pas! bc est là pour vous:

bc <<< "$num1 + $num2"
echo $num1 + $num2 | bc

Cela dit, il y a un certains sans rapport avec les améliorations que vous pourriez faire à votre script

#!/bin/bash

num=0
metab=0

for ((i=1; i<=2; i++)); do
    for j in output-$i-* ; do # for can glob directly, no need to ls
            echo "$j"

             # grep can read files, no need to use cat
            metab=$(grep EndBuffer "$j" | awk '{sum+=$2} END { print sum/120}')
            num=$(( $num + $metab ))
    done
    echo "$num"
done

EDIT:

Comme décrit dans BASH FAQ 022, bash ne supporte pas les nombres à virgule flottante. Si vous avez besoin de la somme des nombres de virgule flottante de l'utilisation d'un outil externe (comme bc ou dc) est nécessaire.

Dans ce cas, la solution serait

num=$(dc <<<"$num $metab + p")

Pour ajouter accumuler éventuellement-les nombres à virgule flottante en num.

26voto

glenn jackman Points 69748

En bash,

  num=5
 x=6
 (( num += x ))
 echo $num   # ==> 11
 

Notez que bash ne peut gérer que l'arithmétique des nombres entiers, donc si votre commande awk renvoie une fraction, alors vous voudrez la refaire: voici votre code réécrit un peu pour faire tous les maths dans awk.

 num=0
for ((i=1; i<=2; i++)); do      
    for j in output-$i-*; do
        echo "$j"
        num=$(
           awk -v n="$num" '
               /EndBuffer/ {sum += $2}
               END {print n + (sum/120)}
           ' "$j"
        )
    done
    echo "$num"
done
 

20voto

unixball Points 71

J'aime beaucoup cette méthode, moins d'encombrement:

 count=$[count+1]
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X