2012-06-28 9 views
18

Ich versuche, zwei Dezimalwerte zu vergleichen, aber ich bekomme Fehler. I verwendetWie zwei Dezimalzahlen in bash/awk zu vergleichen?

if [ "$(echo $result1 '>' $result2 | bc -l)" -eq 1 ];then 

wie vom anderen Stack-Überlauf-Thread vorgeschlagen.

Ich bekomme Fehler.

Was ist der richtige Weg?

+0

Was die Fehler? einen Variablennamen falsch geschrieben. – ormaaj

+0

tatsächlich sind die Fehler auf einige andere Probleme zurückzuführen. Das funktioniert gut. –

+0

Was meinen Sie mit 'Dezimalwerte'? Meinst du ganze Zahlen in Basis 10, oder meinen Sie Zeichenfolgen, die nicht ganzzahlige reelle Werte darstellen? –

Antwort

29

Sie können es Bash numerischen Zusammenhang mit:

if (($(echo "$result1 > $result2" | bc -l))); then 

bc Wille Ausgang 0 oder 1 und die (()) interpretiert sie als wahr oder falsch sind.

Das gleiche mit AWK:

if (($(echo "$result1 $result2" | awk '{print ($1 > $2)}'))); then 
+10

+1 für die awk Lösung, aber: 'wenn echo $ result1 $ result2 | awk '{exit! ($ 1> $ 2)}}; dann ... ' –

+0

Ich möchte meine Down-Abstimmung zurückziehen, da Dennis 'Antwort mit Dezimalpunkten korrekt ist. Für erweiterte Gleitkommaarithmetik mit Bash, siehe meine Antwort unten. – Samir

+0

@Samir: Wenn Sie es nicht bereits getan haben, können Sie erneut auf den Abwärtspfeil klicken, um den Downvote rückgängig zu machen. –

-1

Sie können auch echo eine if...else Aussage bc.

- echo $result1 '>' $result2 
+ echo "if (${result1} > ${result2}) 1 else 0" 

(
#export IFS=2 # example why quoting is important 
result1="2.3" 
result2="1.7" 
if [ "$(echo $result1 '>' $result2 | bc -l)" -eq 1 ]; then echo yes; else echo no;fi 
if [ "$(echo "if (${result1} > ${result2}) 1 else 0" | bc -l)" -eq 1 ];then echo yes; else echo no; fi 
if echo $result1 $result2 | awk '{exit !($1 > $2)}'; then echo yes; else echo no; fi 
) 
8
if awk 'BEGIN{exit ARGV[1]>ARGV[2]}' "$z" "$y" 
then 
    echo z not greater than y 
else 
    echo z greater than y 
fi 
-3

Warum bc verwenden?

for i in $(seq -3 0.5 4) ; do echo $i ; if [[ (("$i" < 2)) ]] ; then echo "... is < 2";fi; done 

Das einzige Problem: der Vergleich „<“ funktioniert nicht mit negativen Zahlen: sie als ihren Absolutwert genommen werden.

+0

'<' inside '[[...]]' steht für den String Vergleich (also '20' ist kleiner als' 3' und '0.2' ist kleiner als' 1e-50'). Die '(' s sind überflüssig, Sie können so viele hinzufügen, wie Sie wollen, sie dienen nur zum Gruppieren. –

-2

Kann Force-Typ-Konvertierung nicht bash? Zum Beispiel:

($result1 + 0) < ($result2 + 0) 
+0

Kein Bash kann Typkonvertierung erzwingen, wie Perl, etc ... –

0

Im Anschluss an Dennis Antwort auf:

Obwohl seine Antwort richtig für Dezimalstellen ist, bash wirft (standard_in) 1: Syntaxfehler mit Fließkommaarithmetik.

result1=12 
result2=1.27554e-05 


if (($(echo "$result1 > $result2" | bc -l))); then 
    echo "r1 > r2" 
else 
    echo "r1 < r2" 
fi 

Dies gibt falsche Ausgabe mit einer Warnung, obwohl mit einem Beendigungscode 0.

(standard_in) 1: Syntaxfehler
r1 r2 <

Während keine besteht Klare Lösung dazu (Diskussion thread 1 und thread 2), habe ich folgenden Teil Fix durch Runden von Fließkomma Ergebnisse mit awk gefolgt von der Verwendung von bc Befehl wie in Dennis Antwort und this thread

Runden auf eine gewünschte Dezimalstelle: Im folgenden wird rekursive Verzeichnis Platz in TB mit Abrundung auf der zweiten Dezimalstelle.

result2=$(du -s "/home/foo/videos" | tail -n1 | awk '{$1=$1/(1024^3); printf "%.2f", $1;}') 

Sie können dann bash Arithmetik wie oben oder mit [[ ]] Gehäuse wie in following thread verwenden.

if (($(echo "$result1 > $result2" | bc -l))); then 
    echo "r1 > r2" 
else 
    echo "r1 < r2" 
fi 

oder mit -eq Operator wo bc Ausgabe von 1 wahr und 0 ist falsch

if [[ $(bc <<< "$result1 < $result2") -eq 1 ]]; then 
    echo "r1 < r2" 
else 
    echo "r1 > r2" 
fi 
0
if [[ `echo "$result1 $result2" | awk '{print ($1 > $2)}'` == 1 ]]; then 
    echo "$result1 is greater than $result2" 
fi