シェルスクリプトのif-else文と浮動小数点数の比較

シェルスクリプトのif-else文と浮動小数点数の比較

だから私は成績入力を受け、各セクションの重みに基づいて成績を計算するスクリプトを書いてきました。最後に計算された成績に基づいて文字評価を出力します。私のコードはif-else文まで問題ありませんが、各if-else文の条件で誤った数値エラーが発生し始めます。

#!/bin/sh
#Calculate weighted grade and output grade letter

echo "What is your total Lab/Assignments grade?"
read labGrade
echo "What is your Midterm grade?"
read midtermGrade
echo "What is your total Quizzes grade?"
read quizGrade
echo "What is your Final Exam grade?"
read finalGrade

weightedLab=`echo "0.25*$labGrade" | bc`
weightedMidterm=`echo "0.30*$midtermGrade" | bc`
weightedQuiz=`echo "0.15*$quizGrade" | bc`
weightedFinal=`echo "0.30*$finalGrade" | bc`

totalGrade=`echo "$weightedLab + $weightedMidterm + $weightedQuiz + $weightedFinal" | bc`

if [ $totalGrade -ge 90.00 ]
then
        echo "Your total grade is an A+!"
elif [ $totalGrade -ge 85.00 -a $totalGrade -le 89.00 ]
then
        echo "Your total grade is an A!"
elif [ $totalGrade -ge 80.00 -a $totalGrade -le 84.00 ]
then
       echo "Your total grade is an A-!"
elif [ $totalGrade -ge 76.00 -a $totalGrade -le 79.00 ]
then
        echo "Your total grade is a B+"
elif [ $totalGrade -ge 72.00 -a $totalGrade -le 75.00 ]
then
        echo "Your total grade is a B"
elif [ $totalGrade -ge 68.00 -a $totalGrade -le 71.00 ]
then
        echo "Your total grade is a B-"
elif [ $totalGrade -ge 64.00 -a $totalGrade -le 67.00 ]
then
        echo "Your total grade is a C+"
elif [ $totalGrade -ge 60.00 -a $totalGrade -le 63.00 ]
then
        echo "Your total grade is a C"
elif [ $totalGrade -ge 56.00 -a $totalGrade -le 59.00 ]
then
        echo "Your total grade is a C-"
elif [ $totalGrade -ge 50.00 -a $totalGrade -le 55.00 ]
then
        echo "Your total grade is a D"
else
        echo "Your total grade is an F"
fi
What is your total Lab/Assignments grade?
100
What is your Midterm grade?
100
What is your total Quizzes grade?
100
What is your Final Exam grade?
90
./A2.sh: 20: [: Illegal number: 97.00
./A2.sh: 23: [: Illegal number: 97.00
./A2.sh: 26: [: Illegal number: 97.00
./A2.sh: 29: [: Illegal number: 97.00
./A2.sh: 32: [: Illegal number: 97.00
./A2.sh: 35: [: Illegal number: 97.00
./A2.sh: 38: [: Illegal number: 97.00
./A2.sh: 41: [: Illegal number: 97.00
./A2.sh: 44: [: Illegal number: 97.00
./A2.sh: 47: [: Illegal number: 97.00
Your total grade is an F

この値を正しく比較するには、コードをどのように変更する必要がありますか?

答え1

Bashは浮動小数点演算を実行しません。

ただし、任意の比率が不要なため、整数が残るように数字を100に拡大して計算を行います。

lab=100 midterm=70 quiz=90 exam=80
total=$((25*lab + 30*midterm + 15*quiz + 30*exam))
if (( total >= 8000 )); then
    echo "you scored at least 80! (actually $(( total / 100 )))"
fi

または、浮動小数点数を処理できる他のツールを使用できます。以下を参照してください。
Bashまたは他の言語/フレームワークで整数および浮動小数点計算を実行するには?

答え2

まず、bash整数のみを処理できます。したがって、浮動小数点比較のために外部も使用する必要があります。

簡単な方法は、bcFALSE文とTRUE文から出力される比較演算子を使用することです。 、、、、および。彼らはあなたがすでに知っているように動作します。01<<=>>===!=

 echo '1 > 2' | bc -l
 0
 echo '1 <= 2' | bc -l
 1

したがって、テストを次のように変更します。

 [ $(echo "$totalGrade >= 90.00" | bc -l) -eq 1 ]

など。

ヒント1

elif [ $totalGrade -ge 80.00 -a $totalGrade -le 84.00 ]

この式では、-a $totalGrade -le 84.00IFループはスクリプトと同じ順序で評価されるため、重複するため、$totalGrade -le 84.00FALSEの場合はすでに処理されています$totalGrade -ge 85.00

ヒント2成績が84.5の場合はどうなりますか?評価では、これらの値は無視されます。

関連情報