it-swarm.com.de

Wie kann ich Zahlen in ein Bash-Skript einfügen?

Ich habe dieses Bash-Skript und ich hatte ein Problem in Zeile 16. Wie kann ich das vorherige Ergebnis von Zeile 15 nehmen und es der Variablen in Zeile 16 hinzufügen?

#!/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
498
Nick

Für ganze Zahlen :

  • Verwenden Sie arithmetische Erweiterung : $((EXPR))

    num=$((num1 + num2))
    num=$(($num1 + $num2))       # also works
    num=$((num1 + 2 + 3))        # ...
    num=$[num1+num2]             # old, deprecated arithmetic expression syntax
    
  • Verwenden des externen Dienstprogramms expr. Beachten Sie, dass dies nur für wirklich alte Systeme erforderlich ist.

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

Für Gleitkomma :

Bash unterstützt dies nicht direkt, aber es gibt einige externe Tools, die Sie verwenden können:

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

Sie können auch die wissenschaftliche Notation verwenden (z. B .: 2.5e+2).


Häufige Fallstricke :

  • Wenn Sie eine Variable setzen, dürfen Sie auf keiner Seite von = ein Leerzeichen setzen. Andernfalls wird die Shell gezwungen, das erste Wort als Namen der auszuführenden Anwendung zu interpretieren (z. B .: num= oder num)

    num= 1num =2

  • bc und expr erwarten, dass jede Zahl und jeder Operator ein separates Argument ist. Leerzeichen sind daher wichtig. Sie können keine Argumente wie 3++4 verarbeiten.

    num=`expr $num1+ $num2`

878
Karoly Horvath

Verwenden Sie die arithmetische Erweiterung $(( )).

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

Weitere Informationen finden Sie unter http://tldp.org/LDP/abs/html/arithexp.html .

88
Steve Prentice

Es gibt tausend und eine Möglichkeit, dies zu tun. Hier ist einer, der dc verwendet:

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

Aber wenn Ihnen das zu peinlich ist (oder Portabilität wichtig ist), könnten Sie sagen

echo $num1 $num2 + p | dc

Aber vielleicht gehören Sie zu den Leuten, die RPN für eklig und verrückt halten. Mach dir keine Sorgen! bc ist für Sie da:

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

Das heißt, es gibt einige unabhängige Verbesserungen, die Sie an Ihrem Skript vornehmen könnten

#!/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

BEARBEITEN:

Wie in BASH FAQ 022 beschrieben, unterstützt bash keine Gleitkommazahlen. Wenn Sie Gleitkommazahlen summieren müssen, ist die Verwendung eines externen Werkzeugs (wie bc oder dc) erforderlich.

In diesem Fall wäre die Lösung

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

Addieren von Gleitkommazahlen in num.

27
Sorpigal

In Bash,

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

Beachten Sie, dass bash nur Ganzzahl-Arithmetik verarbeiten kann. Wenn Ihr awk-Befehl also einen Bruch zurückgibt, sollten Sie neu entwerfen: Hier ist Ihr Code ein wenig umgeschrieben, um alle mathematischen Aufgaben in awk auszuführen.

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
22
glenn jackman

Ich vergesse immer die Syntax, also komme ich zu Google, aber dann finde ich nie die, mit der ich vertraut bin: P. Dies ist für mich am saubersten und entspricht eher dem, was ich in anderen Sprachen erwarten würde.

i=0
((i++))

echo $i;
16
ssshake

Ich mag diese Methode auch sehr, weniger Unordnung:

count=$[count+1]
15
unixball
 #!/bin/bash
read X
read Y
echo "$(($X+$Y))"
11
Amarjeet Singh

Sie sollten Metab als Ganzzahl deklarieren und dann die arithmetische Auswertung verwenden

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

Weitere Informationen finden Sie unter https://www.gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html#Shell-Arithmetic

8
Pavel

Eine weitere tragbare POSIX kompatible Methode, die in bash als Funktion in .bashrc für alle praktischen arithmetischen Operatoren definiert werden kann.

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

und rufen Sie es einfach in der Befehlszeile als,

addNumbers 1 2 3 4 5 100
115

Die Idee ist, das Input-Field-Separator (IFS) zu verwenden, eine spezielle Variable in bash, die zum Teilen von Wörtern nach der Erweiterung und zum Teilen von Zeilen in Wörter verwendet wird. Die Funktion ändert den Wert lokal, um das Worttrennungszeichen als Summenoperator + zu verwenden.

Denken Sie daran, dass IFS lokal geändert wird und NICHT Auswirkungen auf das Standardverhalten IFS außerhalb des Funktionsbereichs hat. Ein Auszug aus der man bash Seite,

Die Shell behandelt jedes IFS-Zeichen als Trennzeichen und teilt die Ergebnisse der anderen Erweiterungen in Wörter für diese Zeichen auf. Wenn IFS nicht gesetzt oder sein Wert genau der Standardwert ist, werden die Folgen von und am Anfang und Ende der Ergebnisse der vorherigen Erweiterungen ignoriert und jede Folge von IFS-Zeichen, die nicht am Anfang oder Ende steht, dient zur Begrenzung Wörter.

Die "$(( $* ))" repräsentiert die Liste der Argumente, die zur Aufteilung durch + übergeben wurden, und später wird der Summenwert mit der Funktion printf ausgegeben. Die Funktion kann erweitert werden, um Spielraum für andere arithmetische Operationen hinzuzufügen.

6
Inian
#!/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
2