设置变量以便稍后在case构造中使用

时间:2018-02-09 04:29:25

标签: linux bash shell conditional

我有这个练习题,要求我把我现有的代码和字母等级的变量插入到现有的“IF”语句中,以便在根据指定的字母等级读取句子的案例构造中使用。我遇到的问题是如何设置变量,即。我需要为变量做一个全新的IF / ECHO线吗?我怎么能在第一时间说出来呢?

会是等级= A吗?

这是我到目前为止所做的:(已编辑包含建议)

#!/bin/bash
# Bash shell script to calculate student average
# Usage: ./grade1.sh

# Declare some integer type variables
declare -i test1
declare -i test2
declare -i test3
declare -i test4
declare -i lab
declare -i sum

echo
echo "=================="
echo "Grade Calculator  "
echo "=================="
echo
read -p "Enter first name: " firstname
read -p "Enter last name: " lastname
echo
read -p "Enter test score 1: " test1
read -p "Enter test score 2: " test2
read -p "Enter test score 3: " test3
read -p "Enter test score 4: " test4
read -p "Enter lab score: " lab

sum=$test1+$test2+$test3+$test4+$lab
average=$((sum/5))

VAR1=A
VAR2=B
VAR3=C
VAR4=D
VAR5=F

if [ $average -ge 90 ]; then
   echo "Course grade: $VAR1"    
elif [ $average -ge 80 ]; then
   echo "Course grade: $VAR2"
elif [ $average -ge 70 ]; then
   echo "Course grade: $VAR3"
elif [ $average -ge 60 ]; then
   echo "Course grade: $VAR4"
elif [ $average -le 60 ]; then
   echo "Course grade: $VAR5"
fi

echo
echo "Grade results . . ."
echo "Student name: $firstname $lastname"
echo "Total points: $sum"
echo "Course average: $average"
echo

case $grade in

A) echo "An 'A' represents superior course work."
    ;;
B) echo "A 'B' represents above average course work."
    ;;
C) echo "A 'C' represents average course work."
    ;;
D) echo "A 'D' represents below average course work."
    ;;
F) echo "An 'F' represents failing course work."
    ;;
esac

2 个答案:

答案 0 :(得分:1)

正如你所说的那样,任务没有多大意义......如果我们有等级的数量和门槛完全可变,那将是有意义的。但是,这是一个练习题,所以他们可能会要求你做一些废话,只是为了练习。

由于这是一个练习,我会给你一些指示,但不要写下整个解决方案。

假设你真的应该在这里做你所要求的(而且没有误解任务),你应该用变量替换文字成绩(A,B,C,D,F)。由于您有5个等级,因此您需要5个变量或5个元素的数组。你问了变量,所以对于这个练习,这是要走的路。

由于您有5个变量,因此需要创建5个不同的名称,例如

this=A
is=B
a=C
silly=D
exercise=F # Note: grade E does not exist

您可以在首次使用之前在某处编写这些定义,并随意使用更适合您的变量名称。现在bash知道这些变量,你可以使用它们,例如:

elif [ $average -ge 60 ]; then
  echo "Course grade: $silly"

现在有两件事你没有要求,但可能有兴趣知道:

首先,代码中average的计算不正确。如果将所有测试和实验室设置为1,则平均为5(尝试一下)。

其次,在case语句中,您使用的变量grade,您没有在任何地方设置。例如,在您发现等级为D的地方(并且您确实发现了这一点,因为您执行了此事实的echo),您应该设置变量

 grade=$silly

答案 1 :(得分:1)

在这种情况下,您可以通过利用数组来帮助您构建文本输出并让字符类让shell(bash专门)帮助您解决问题在case声明中帮助匹配。

例如,由于您知道自己正在对传统的A-F 90-50断点进行评分,因此您可以创建多个数组以允许您索引所有相关信息,例如

ltrgrades=(  A  B  C  D  F )
numgrades=( 90 80 70 60 50 )
prefixes=(  An  A  A  A An )
comments=(  "superior"
            "above average"
            "average"
            "below average"
            "failing" )

函数可以通过将关联的索引作为第一个参数传递来处理每个学生的所有输出需求:

results() {
    echo
    echo "Grade results . . ."
    echo "Student name  : $firstname $lastname"
    echo "Total points  : $sum"
    echo "Course average: $average"
    echo
    echo "Course grade  : ${ltrgrades[$1]}"
    echo
    echo "${prefixes[$1]} '${ltrgrades[$1]}' represents ${comments[$1]} course work."
}

利用heredoc简化了提供多行输出:

## use a heredoc for multi-line text
cat << EOF
"=================="
"Grade Calculator  "
"=================="
EOF

注意:您可以在results函数中使用heredoc)

最后,您可以使用字符类作为case匹配项和'*'来标记默认情况,例如

case "${average%.*}" in
    1??     )   results 0;;
    9[0-9]  )   results 0;;
    8[0-9]  )   results 1;;
    7[0-9]  )   results 2;;
    6[0-9]  )   results 3;;
    *       )   results 4;;
esac

完全放弃,你可以这样做:

#!/bin/bash
# Bash shell script to calculate student average
# Usage: ./grade1.sh

ltrgrades=(  A  B  C  D  F )
numgrades=( 90 80 70 60 50 )
prefixes=(  An  A  A  A An )
comments=(  "superior"
            "above average"
            "average"
            "below average"
            "failing" )

results() {
    echo
    echo "Grade results . . ."
    echo "Student name  : $firstname $lastname"
    echo "Total points  : $sum"
    echo "Course average: $average"
    echo
    echo "Course grade  : ${ltrgrades[$1]}"
    echo
    echo "${prefixes[$1]} '${ltrgrades[$1]}' represents ${comments[$1]} course work."
}

## use a heredoc for multi-line text
cat << EOF
"=================="
"Grade Calculator  "
"=================="
EOF

read -p "Enter first name  : " firstname
read -p "Enter last name   : " lastname
echo
read -p "Enter test score 1: " test1
read -p "Enter test score 2: " test2
read -p "Enter test score 3: " test3
read -p "Enter test score 4: " test4
read -p "Enter lab score   : " lab

sum=$((test1 + test2 + test3 + test4 + lab))
average=$(echo "scale=2; $sum / 5" | bc)

case "${average%.*}" in
    1??     )   results 0;;
    9[0-9]  )   results 0;;
    8[0-9]  )   results 1;;
    7[0-9]  )   results 2;;
    6[0-9]  )   results 3;;
    *       )   results 4;;
esac

示例使用/输出

$ bash grades.sh
"=================="
"Grade Calculator  "
"=================="
Enter first name  : John
Enter last name   : Doe

Enter test score 1: 85
Enter test score 2: 93
Enter test score 3: 94
Enter test score 4: 91
Enter lab score   : 92

Grade results . . .
Student name  : John Doe
Total points  : 455
Course average: 91.00

Course grade  : A

An 'A' represents superior course work.


$ bash grades.sh
"=================="
"Grade Calculator  "
"=================="
Enter first name  : Mary
Enter last name   : Jane

Enter test score 1: 86
Enter test score 2: 93
Enter test score 3: 72
Enter test score 4: 71
Enter lab score   : 77

Grade results . . .
Student name  : Mary Jane
Total points  : 399
Course average: 79.80

Course grade  : C

A 'C' represents average course work.


$ bash grades.sh
"=================="
"Grade Calculator  "
"=================="
Enter first name  : Sally
Enter last name   : Smith

Enter test score 1: 55
Enter test score 2: 61
Enter test score 3: 42
Enter test score 4: 58
Enter lab score   : 59

Grade results . . .
Student name  : Sally Smith
Total points  : 275
Course average: 55.00

Course grade  : F

An 'F' represents failing course work.

由于使用bc将等级计算为浮点值,因此您可以(也可能应该)处理舍入(例如79.5轮到80而{{1}保留79.4。您可以使用另一个变量79来处理它,其类似于:

score

现在sum=$((test1 + test2 + test3 + test4 + lab)) average=$(echo "scale=2; $sum / 5" | bc) fract=${average#*.} score=${average%.*} (( ${fract:0:1} >= '5')) && ((score++)) case $score in 1?? ) results 0;; 9[0-9] ) results 0;; 8[0-9] ) results 1;; 7[0-9] ) results 2;; 6[0-9] ) results 3;; * ) results 4;; esac 等级平均为Mary Jane's的四舍五入为79.80一个80而不是B。由您决定如何处理舍入,这只是一种方法。您可以重新编写C以显示计算的results和舍入的average,例如。

score