Hoe kan ik nummers toevoegen in een bash-script?

Ik heb dit bash-script en ik had een probleem in lijn 16.
Hoe kan ik het vorige resultaat van regel 15 nemen en toevoegen
het naar de variabele in lijn 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

1, Autoriteit 100%

voor gehele getallen :

  • Gebruik rekenkundige expansie : $((EXPR))

    num=$((num1 + num2))
    num=$(($num1 + $num2))       # Also works
    num=$((num1 + 2 + 3))        # ...
    num=$[num1+num2]             # Old, deprecated arithmetic expression syntax
    
  • Gebruik de externe exprUtility. Merk op dat dit alleen nodig is voor echt oude systemen.

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

voor zwevende punt :

bash ondersteunt dit niet direct, maar er zijn een paar externe hulpmiddelen die u kunt gebruiken:

num=$(awk "BEGIN {print $num1+$num2; exit}")
num=$(python -c "print $num1+$num2")
num=$(perl -e "print $num1+$num2")
num=$(echo $num1 + $num2 | bc)   # Whitespace for echo is important

U kunt ook wetenschappelijke notatie gebruiken (bijvoorbeeld 2.5e+2).


Gemeenschappelijke valkuilen :

  • Bij het instellen van een variabele, kunt u geen WhiteSpace aan weerszijden van =hebben, anders dwingt het de schaal om het eerste woord te interpreteren als de naam van de toepassing (bijvoorbeeld , num=OF num)

    num= 1num =2

  • bcEN exprVerwacht elk nummer en de exploitant als een afzonderlijk argument, dus WhiteSpace is belangrijk. Ze kunnen geen argumenten zoals 3++4verwerken.

    num=`expr $num1+ $num2`


2, Autoriteit 14%

Gebruik de $(( ))rekenkundige expansie.

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

Zie hoofdstuk 13. Rekenkundige expansie voor Meer informatie.


3, Autoriteit 3%

Er zijn duizend en één manieren om het te doen. Dit is er een met behulp van dc(een Reverse-Polish bureau-rekenmachine die ondersteunt onbeperkte precisie rekenkunde):

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

Maar als dat te bash-y voor u (of draagbaarheidszaken) zou kunnen zeggen

echo $num1 $num2 + p | dc

Maar misschien ben je een van die mensen die denkt dat RPN icky en raar is; Maak je geen zorgen! bcis hier voor u:

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

Dat gezegd hebbende, zijn er enkele ongerelateerde verbeteringen die je zou kunnen aanbrengen in je 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

Zoals beschreven in Bash FAQ 022, ondersteunt Bash native geen floating point getallen. Als u getallen met drijvende komma moet optellen, is het gebruik van een externe tool (zoals bcof dc) vereist.

In dit geval zou de oplossing zijn

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

Om cumulatieve getallen met mogelijk drijvende komma toe te voegen aan num.


Antwoord 4, autoriteit 2%

In bas,

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

Houd er rekening mee dat bash alleen met gehele getallen kan rekenen, dus als je awk-commando een breuk retourneert, moet je het opnieuw ontwerpen: hier is je code een beetje herschreven om alle wiskunde in awk uit te voeren.

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

Antwoord 5, autoriteit 2%

Ik vergeet altijd de syntaxis, dus ik kom naar Google, maar dan vind ik nooit degene die ik ken: p. Dit is het schoonst voor mij en meer waar aan wat ik in andere talen zou verwachten.

i=0
((i++))
echo $i;

6, Autoriteit 2%

#!/bin/bash
read X
read Y
echo "$(($X+$Y))"

7

Ik hou ook van deze methode ook, minder rommel:

count=$[count+1]

8

U moet metab verklaren als geheel getal en vervolgens rekenkundige evaluatie gebruiken

declare -i metab num
...
num+=metab
...

Zie voor meer informatie https: // www.gnu.org/software/bash/manual/html_node/shell-arithmetic.html#shell-arithmetic


9

Nog een draagbare POSIXComplante manier om te doen in bash, die kan worden gedefinieerd als een functie in .bashrcvoor alle rekenkundige exploitanten van gemak.

addNumbers () {
    local IFS='+'
    printf "%s\n" "$(( $* ))"
}

en noem het gewoon in opdrachtregel als,

addNumbers 1 2 3 4 5 100
115

Het idee is om de Input-Field-Separator(IFS)te gebruiken, een speciale variabele in bashgebruikt voor het splitsen van woorden na expansie en om regels in woorden te splitsen. De functie verandert de waarde lokaal om woordsplitsende tekens te gebruiken als de som-operator +.

Onthoud dat de IFSlokaal wordt gewijzigd en NIETeffect heeft op het standaard IFS-gedrag buiten het functiebereik. Een fragment van de man bashpagina,

De shell behandelt elk teken van IFS als een scheidingsteken en splitst de resultaten van de andere uitbreidingen in woorden op deze tekens. Als IFS niet is ingesteld, of de waarde is exact , de standaardwaarde, dan worden reeksen van , , en aan het begin en einde van de resultaten van de vorige uitbreidingen genegeerd, en elke reeks IFS-tekens die niet aan het begin of einde staan, dient ter begrenzing woorden.

De "$(( $* ))"vertegenwoordigt de lijst met argumenten die zijn doorgegeven om te worden gesplitst door +en later wordt de somwaarde uitgevoerd met behulp van de printffunctie. De functie kan worden uitgebreid om ook ruimte voor andere rekenkundige bewerkingen toe te voegen.


Antwoord 10

#!/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)
        let num=num+metab (line 16)
    done
    echo "$num"
done

Other episodes