Ich versuche, den Prozentsatz bestimmter Elemente in Shell Script zu berechnen. Ich möchte den Wert abrunden, das heißt, wenn das Ergebnis 59,5 ist, sollte ich 60 und nicht 59 erwarten.
%Vor%Dies ergibt 42.
Aber tatsächlich ist das Ergebnis 42,8 und ich würde es auf 43 runden. "bc" macht den Trick, gibt es einen Weg ohne "bc" zu benutzen?
Ich bin nicht berechtigt, neue Pakete zu installieren. "dc" und "bc" sind in meinem System nicht vorhanden. Es sollte reine Shell sein, kann Perl- oder Python-Skripte nicht verwenden
Nimmt man 2 * die ursprüngliche Prozentberechnung und erhält man den Modulo 2 davon, wird das Inkrement zum Runden bereitgestellt.
%Vor%(getestet mit Bash, Ash, Dash und Ksh)
Dies ist eine schnellere Implementierung als das Abfeuern eines AWK-Coprozesses:
%Vor%Ein POSIX-kompatible Shell-Skript ist beschränkt auf integer Arithmetik mit der Shell-Sprache (" nur lange integer-Arithmetik unterzeichnete erforderlich ist "), so dass rein Shell Lösung muss emulieren Gleitkommazahlen Arithmetik:
%Vor%100 * item / total
liefert das abgeschnittene Ergebnis der Division ganze Zahl als Prozentsatz. 1000 * item / total % 10 >= 5 ? 1 : 0
berechnet die 1. Dezimalstelle, und wenn sie gleich oder größer als 5 ist, addiert man 1 zum ganzzahligen Ergebnis, um es aufzurunden. $
in einer arithmetischen Erweiterung $((...))
voranzuzfügen. Wenn - im Gegensatz zur Prämisse der Frage - die Verwendung von externen Dienstprogrammen akzeptabel ist:
awk
bietet eine einfache Lösung, die jedoch mit dem caveat versehen ist, dass sie echte binäre Gleitkommawerte mit doppelter Genauigkeit und may verwendet daher ergeben unerwartete Ergebnisse in dezimal Darstellung - zB versuchen printf '%.0f\n' 28.5
, die Ausbeuten 28
anstatt der erwarteten 29
): -v
verwendet wird, um Variablen für das Skript awk
zu definieren, das eine saubere Trennung zwischen dem einfach zitierten und daher Literal % co_de ermöglicht % Skript und alle Werte, die von der Shell an übergeben werden. awk
ist ein POSIX-Dienstprogramm (und daher zu erwarten, kann auf den meisten Unix-ähnlichen Plattformen sein) und führt beliebiger Genauigkeit Arithmetik, es immer Verkürzungen die Ergebnisse, so dass Rundung muss von einem anderen -Dienstprogramm ausgeführt werden; aber bc
, obwohl es ist ein POSIX-Dienstprogramm im Prinzip , ist nicht erforderlich zur Unterstützung von Fließkommaformatbezeichnern (wie in printf
oben verwendet), so dass das folgende funktioniert oder nicht funktioniert (und ist angesichts der einfacheren Methode nicht die Mühe wert awk
solution, und da die Genauigkeitsprobleme aufgrund der Fließkomma-Arithmetik wieder im Bild sind): Das Folgende basiert auf meiner zweiten Antwort, aber mit expr und Back-Ticks - die (vielleicht auch abscheulich für die meisten) angepasst werden können, um in even zu arbeiten die archaischsten Muscheln nativ:
%Vor%Tags und Links linux shell percentage