Математические уравнения с использованием операторов if-else

Я получаю несколько ошибок при использовании тестового скрипта для достижения определенного результата.

Я хочу рассчитать список слов из документа, который хранится в папке, а затем

переменная "wword" количество слов, которые были правильными. Всего 17 слов. Это число (15), конечно, будет изменено на основе пользовательского ввода, поэтому аргумент переменной "wword"

Текущие проблемы, которые у меня есть, это "ожидается унарный оператор" и что эта строка кода gradel=$('"$wword"' - 17) не вставляет $wword переменная должна быть 15. Что я делаю не так?

wword="15"

gradel=$('"$wword"' - 17)
gradel=$('"$gradel"' / 17)



if [ "$gradel" => "1" ] 
then 
  gradel="A+" 

elif [ "$gradel" => ".90" ] 
then
  gradel="A"

elif [ "$gradel" => ".85" ] 
then
  gradel=“B+”

elif [ "$gradel" => ".80" ] 
then
  gradel=“B”

elif [ "$gradel" => ".75" ] 
then
  gradel=“C”

elif [ "$gradel" =>  ".70" ] 
then
  gradel=“C-”

elif [ "$gradel" => ".65" ] 
then
  gradel="D"

else
  gradel="F"   

fi

echo "$gradel"

2 ответа

Решение

Bash не поддерживает арифметику с плавающей запятой, поэтому вам понадобится такой инструмент, как awk. Вот пример:

wword=$1
grade=$((17-wword))
awk -v g="$grade" 'BEGIN{a=g/17}a>=$1{print $2;exit}' << EOF
1    A+
0.9  A
0.85 B+
0.80 B
0.75 C
0.70 C-
0.65 D
-1   F
EOF

В этой программе много мелких проблем:

  • Вы пытаетесь сделать арифметику в

    gradel=$('"$wword"' - 17)
    

    но это на самом деле пытается запустить содержимое $( ) как команда. Ты хочешь $(( )) для арифметического расширения.

  • '"$wword"' расширяется до "$wword": одинарные кавычки препятствуют расширению. Ты хочешь "$wword", (В $(( ))даже просто wword достаточно).

  • Вы сравниваете числа в [ ] с =>, Во всяком случае, это должно быть >=и для чисел в [ ] ты должен использовать -ge вместо этого в любом случае.

  • gradel=“B+” использует нестандартные двойные кавычки.

И самая большая проблема: Bash не может выполнять вычисления с плавающей запятой. Люди часто используют для этого bc (или awk, Perl, Python...). Это небольшая программа bc, которая делает то, что вы хотите сделать:

#!/usr/bin/bc -q
# -q suppresses the copryight message

# Use floating point with three digits after period
scale = 3

# Read from standard input
wword = read()
gradel = (17 - wword) / 17

if (gradel >= 1) {
    print "A+\n"
} else if (gradel >= 0.9) {
    print "A\n"
} else if (gradel >= 0.85) {
    print "B+\n"
} else if (gradel >= 0.8) {
    print "B\n"
} else if (gradel >= 0.75) {
    print "C\n"
} else if (gradel >= 0.7) {
    print "C-\n"
} else if (gradel >= 0.65) {
    print "D\n"
} else {
    print "F\n"
}

quit

Используется так:

$ for i in 0 1 2 3 4 5 5.5 6; do ./so <<< "$i"; done
A+
A
B+
B
C
C-
D
F

где so это имя сценария.


В общем, если все, что вам нужно, - это одно (или несколько) сравнений с плавающей запятой как части скрипта Bash, вы можете встроить bc следующим образом:

if (( $(bc <<< "$var > 0.9") )); then
    echo "$var is greater than 0.9"
else
    echo "$var is not greater than 0.9"
fi

где "$var" переменная Bash с плавающей точкой, которую вы хотите сравнить 0.9,

Это использует преимущества печати до н.э. 1 для истинного сравнения и 0 для ложного сравнения. (( )) затем преобразует это в состояние выхода.

Другие вопросы по тегам