Ich lese eine Datei mit mehreren Spalten und speichere 2 Spalten der Datei in 2 verschiedene Arrays. Basierend auf einer Bedingung muss ich nun die Differenz zwischen zwei aus dem Array abgerufenen Werten ermitteln. Mein Code sieht also so aus -

if [ condition ]; then
VAL = (( ${local[$x]} - ${local[$y]} ))
fi

Die Sache ist, während ich beide Werte ${local[$x]} und ${local[$y]} wiedergeben und sehen kann, gibt mir die Subtraktionsoperation einen Syntaxfehler. Ich verstehe, dass dies fehlschlägt, da die derzeit im Array enthaltenen Werte Gleitkomma-Dezimalwerte enthalten - wie 3456712.126758 - und die Zuweisung Fehler mit dem Dezimalteil auslöst. Ich verstehe, dass arithmetische Operationen keine Stärke der Bash-Shell sind, da Gleitkommazahlen als Zeichenfolgen betrachtet werden, daher das Problem.

Könnten Sie bitte helfen, das richtige Format zu finden? Soll ich so etwas machen?

VAL= awk '{ print ${local[$x]} - ${local[$y]} }'

Oder

VAL=echo ${local[$x]} - ${local[$y]} | bc -l

Ich bin sicher, dass die obige Syntax falsch ist. Bitte helfen Sie bei der Syntax. Ich muss das subtrahierte Ergebnis dem Feld VAL zuweisen.

0
zephyr 23 Dez. 2015 im 04:25

2 Antworten

Beste Antwort

Nicht nur Gleitkommawerte, sondern auch der Abstand würden zu Syntaxfehlern führen. Bash-Variablenzuweisungen dürfen keine Leerzeichen wie in val=x und nicht val = x enthalten.

Variablennamen in Großbuchstaben sind für Umgebungsvariablen reserviert. Es wird empfohlen, stattdessen Kleinbuchstaben für Ihre eigenen Variablen zu verwenden. (Oh, und local ist auch ein reserviertes Wort.)

Ihre Aufgabe würde auch nicht mit dem richtigen Abstand funktionieren: arithmetischer Ausdruck

var=(( ${vals[$x]} - ${vals[$y]} ))   # syntax error near unexpected token `('

Bewertet nur seinen Inhalt, gibt aber nichts zurück. Sie können das Teil nach = als Bedingung verwenden. Damit etwas zurückgegeben wird, benötigen Sie eine arithmetische Erweiterung (beachte das zusätzliche $):

var=$(( ${vals[$x]} - ${vals[$y]} ))    # works for integers
    ^

In einem arithmetischen Kontext müssen Sie Ihren Variablen nicht einmal $ voranstellen:

var=$(( vals[x] - vals[y] ))

Funktioniert genauso gut. Ausnahme: In assoziativen Arrays müssen Sie dies noch tun es für Indizes:

$(( vals[$x] ))

Und schließlich funktioniert dies, wie Sie bemerkt haben, nicht für Gleitkommazahlen. Anstatt an bc weiterzuleiten, können Sie auch ein hier Zeichenfolge und vermeiden Sie das Laichen einer Unterschale:

$ vals=(1.1 2.2)
$ x=0
$ y=1
$ echo $(( local[x] - local[y] ))    # No '$' needed for variable expansion
bash: 1.1: syntax error: invalid arithmetic operator (error token is ".1")  # But :(
$ bc -l <<< "local[x] - local[y]"   # Requires '$' - these expand to nothing
0
$ bc -l <<< "${local[x]} - ${local[y]}"   # Works!
-1.1
1
Benjamin W. 23 Dez. 2015 im 02:09

Mit awk:

awk -v a=${a} -v b=${b} 'BEGIN{print a - b}'

Mit bc:

echo "${a} - ${b}" | bc -l

Siehe auch andere Optionen hier.

1
Community 13 Apr. 2017 im 12:36