Ich bemühe mich sehr, zwei Gleitkommazahlen in einem Bash-Skript zu vergleichen. Ich muss Variablen, z
let num1=3.17648e-22
let num2=1.5
Jetzt möchte ich nur einen einfachen Vergleich dieser beiden Zahlen durchführen:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
Leider habe ich einige Probleme mit der richtigen Behandlung der num1, die vom "E-Format" sein kann. :((
Jede Hilfe, Hinweise sind willkommen!
Antworten:
Bequemer
Dies kann bequemer unter Verwendung des numerischen Kontexts von Bash erfolgen:
Erläuterung
Das Durchleiten des Basisrechnerbefehls
bc
gibt entweder 1 oder 0 zurück.Die Option
-l
entspricht--mathlib
; Es lädt die Standard-Mathematikbibliothek.Wenn Sie den gesamten Ausdruck in doppelte Klammern setzen,
(( ))
werden diese Werte in wahr bzw. falsch übersetzt.Bitte stellen Sie sicher, dass das
bc
Basisrechnerpaket installiert ist.Dies gilt auch für Floats im wissenschaftlichen Format, sofern ein Großbuchstabe verwendet
E
wird, znum1=3.44E6
quelle
bc
Taschenrechnerpaket installiert haben.0: not found
mit der Aussageif (( $(echo "$TOP_PROCESS_PERCENTAGE > $THRESHOLD" | bc -l) )); then
.bc
Denken Sie bei allen, die "Befehl nicht gefunden" erhalten, daran, dass Sie die entweder in Backticks oder$()
und dann in(( ))
... dh(( $(bc -l<<<"$a>$b") ))
und nicht einschließen müssen(( bc -l<<<"$a>$b" ))
.E
, und alle Syntaxfehler sind verschwunden.bash behandelt nur ganzzahlige Mathematik, aber Sie können den
bc
Befehl wie folgt verwenden:Beachten Sie, dass das Exponentenzeichen in Großbuchstaben geschrieben werden muss
quelle
bc
Tool und das würde ich jedem BASH-Programmierer empfehlen. BASH ist eine typenlose Sprache. Ja, es kann ganzzahlige Arithmetik ausführen, aber für Gleitkommazahlen müssen Sie ein externes Werkzeug verwenden. BC ist das Beste, denn dafür ist es gemacht.Es ist besser,
awk
für nicht ganzzahlige Mathematik zu verwenden. Sie können diese Bash-Dienstprogrammfunktion verwenden:Und nenne es als:
quelle
awk
undbc
in Shell-Skripten ist seit der Antike eine Standardpraxis. Ich würde sagen, dass einige Funktionen Shells nie hinzugefügt wurden, da sie in awk, bc und anderen Unix-Tools verfügbar sind. Keine Notwendigkeit für Reinheit in Shell-Skripten.exit
damit Awk das Ergebnis auf ordnungsgemäße, maschinenlesbare Weise an die Shell zurückgibt.if awk -v n1="123.456" -v n2="3.14159e17" 'BEGIN { exit (n1 <= n2) }' /dev/null; then echo bigger; else echo not; fi
... beachten Sie jedoch, wie die Bedingung invertiert wird (der Exit-Status 0 bedeutet Erfolg für die Shell).python
. Sie habenperl
standardmäßig auf vielen Linux / Unix-Systemen installiert .. sogarphp
auchawk
Lösung ist in meinem Fall robuster als die mit derbc
, die aus einem Grund, den ich nicht erhalten habe, falsche Ergebnisse liefert.Reine Bash-Lösung zum Vergleichen von Floats ohne Exponentialschreibweise, führende oder nachfolgende Nullen:
Die Reihenfolge der logischen Operatoren ist wichtig . Ganzzahlige Teile werden als Zahlen und Bruchteile absichtlich als Zeichenfolgen verglichen. Mit dieser Methode werden Variablen in ganzzahlige und gebrochene Teile aufgeteilt .
Floats werden nicht mit ganzen Zahlen (ohne Punkt) verglichen.
quelle
Sie können awk in Kombination mit einer bash if-Bedingung verwenden. awk gibt 1 oder 0 aus und diese werden durch die if-Klausel mit true oder false interpretiert .
quelle
if (( $(echo $d1 $d2 | awk '{if ($1 > $2) print 1;}') )); then echo "yes"; else echo "no"; fi
Achten Sie beim Vergleichen von Zahlen, die Paketversionen sind, z. B. beim Überprüfen, ob grep 2.20 größer als Version 2.6 ist:
Ich habe ein solches Problem mit einer solchen Shell / Awk-Funktion gelöst:
quelle
dpkg --compare-versions
ist dies häufig nützlich. Es verfügt über die vollständige Logik zum Vergleichen der integrierten Debian-Paketversionen, die komplexer als nur sindx.y
.Wenn Sie keine wirklich Gleitkomma-Arithmetik benötigen, sondern nur Arithmetik für z. B. Dollarwerte, bei denen immer genau zwei Dezimalstellen vorhanden sind, können Sie den Punkt einfach fallen lassen (effektiv mit 100 multiplizieren) und die resultierenden Ganzzahlen vergleichen.
Dazu müssen Sie natürlich sicherstellen, dass beide Werte die gleiche Anzahl von Dezimalstellen haben.
quelle
Ich habe die Antworten von hier verwendet und sie in eine Funktion eingefügt. Sie können sie folgendermaßen verwenden:
Einmal angerufen,
echo $result
wird1
in diesem Fall anders sein0
.Die Funktion:
Oder eine Version mit Debug-Ausgabe:
Speichern Sie die Funktion einfach in einer separaten
.sh
Datei und fügen Sie sie folgendermaßen hinzu:quelle
Ich habe dies als Antwort auf https://stackoverflow.com/a/56415379/1745001 gepostet, als es als Dup dieser Frage geschlossen wurde. Hier ist es also so, wie es auch hier gilt:
Verwenden Sie zur Vereinfachung und Klarheit einfach awk für die Berechnungen, da es sich um ein Standard-UNIX-Tool handelt und daher genauso wahrscheinlich vorhanden ist wie bc und viel einfacher syntaktisch zu bearbeiten ist.
Für diese Frage:
und für diese andere Frage, die als Dup dieser geschlossen wurde:
quelle
Dieses Skript kann hilfreich sein, wenn ich überprüfe, ob die installierte
grails
Version größer als das erforderliche Minimum ist. Ich hoffe es hilft.quelle
quelle
Bitte überprüfen Sie den unten bearbeiteten Code: -
das funktioniert gut.
quelle
awk
und Werkzeuge wie dieses (ich starre dich ansed
...) sollten in den Mülleimer alter Projekte verbannt werden, mit Code, den jeder zu sehr fürchten muss, da er in einer Sprache geschrieben wurde, die niemals gelesen werden kann.Oder Sie sind das relativ seltene Projekt, bei dem die Optimierung der CPU-Auslastung Vorrang vor der Optimierung der Codewartung haben muss. In diesem Fall fahren Sie fort.
Wenn nicht, warum nicht stattdessen einfach etwas Lesbares und Explizites verwenden, wie z
python
. Ihre Mitcodierer und Ihr zukünftiges Selbst werden es Ihnen danken. Sie könnenpython
wie alle anderen auch Inline mit Bash verwenden.quelle
not(...)
anstelle von0 if ... else 1
awk '${print $5}' ptpd_log_file | perl -ne '$_ > 0.000100 && print' > /tmp/outfile
. Kinderleicht. Jede Sprache hat ihren Platz.python -c "import sys; sys.exit(0 if float($num1) < float($num2) else 1)"
ist einfachawk "BEGIN{exit ($num1 > $num2 ? 0 : 1)}"
.Eine Lösung, die alle möglichen Notationen unterstützt, einschließlich der wissenschaftlichen Notation mit Exponenten in Groß- und Kleinbuchstaben (z. B.
12.00e4
):quelle
Verwenden Sie Korn Shell. In Bash müssen Sie möglicherweise den Dezimalteil separat vergleichen
quelle
Mit bashj ( https://sourceforge.net/projects/bashj/ ), einem Bash-Mutanten mit Java-Unterstützung, schreiben Sie einfach (und es ist leicht zu lesen):
Natürlich bietet die Bashj Bash / Java-Hybridisierung viel mehr ...
quelle
Wie wäre es damit? = D.
quelle
exit 0
die Wahrheit melden undexit 1
falsch zurückgeben. dann können Sie das bemerkenswert elegante vereinfachenif awk 'BEGIN { exit (ARGV[1] >= ARGV[2]) ? 0 : 1 }' "$VAL_TO_CHECK" 1; then
... (noch eleganter, wenn Sie das Awk-Skript in eine Shell-Funktion einkapseln).