#!/bin/bash
#完成Shell程序的编写:
#完成一个成绩管理系统
#1、能添加删除修改查询成绩信息;
#2、能存储并计算某学生总分、平均分;
#3、能按某科成绩、总分进行排序显示;
# 定义成绩数据文件的位置
Student_Score=student_score.txt
#注意文件要是utf-8编码不然会乱码
# 学生成绩管理界面
Student_Score_page() {
echo -e "\t-------------欢迎使用学生成绩管理系统---------------"
# -e 开启转义
echo -e "\t* 1. 学生成绩添加. *"
echo -e "\t* 2. 学生成绩修改. *"
echo -e "\t* 3. 学生成绩删除. *"
echo -e "\t* 4. 查看单个学生. *"
echo -e "\t* 5. 按照某一科(或总分)进行排序查看. *"
echo -e "\t* 6. 查看成绩排名(以某一科或总分为分类). *"
echo -e "\t* 0. 退出系统. *"
echo -e "\t----------------------------------------------------"
echo -n "请输入功能选择(0~6):"
}
# 添加成绩函数
add_Score_Info() {
#echo -n表示不在终端中换行,只输出参数指定的文字
echo -n "请输入学生学号:"
read sid
echo -n "请输入姓名:"
read name
echo -n "请输入高数成绩:"
read math
echo -n "请输入英语成绩:"
read english
echo -n "请输入物理成绩:"
read physics
echo -n "请输入政治成绩:"
read politics
echo -n "请输入C语言成绩:"
read cyuyan
total=$((math+english+physics+politics+cyuyan))
avg=$(echo "scale=2; $total/5" | bc)
#符号"|"表示管道操作符。它的作用是将前一个命令的输出作为后一个命令的输入
#将表达式管道传递给bc命令来进行浮点计算,scale=2:结果保留两位小数
echo "$sid,$name,$math,$english,$physics,$politics,$cyuyan,$total,$avg" >> $Student_Score
echo "成绩添加成功!"
echo -n "是否继续添加学生成绩信息(y/n):"
read choice
case $choice in
Y|y)
add_Score_Info
;;
N|n)
echo -e"\n"
;;
*)
echo "无效选择!"
;;
esac
}
# 修改成绩函数
modify_Score_Info() {
echo -n "请输入要修改的学生学号:"
read sid
lineNum=$(grep -n "$sid" $Student_Score | cut -d ":" -f 1)
#cut命令 cut -d '分隔符' -f1:表示使用指定的分隔符将内容分割,并取走分割的第一块内容
#在文件$Student_Score中查找包含子字符串$sid的行,并获取包含该子字符串的行的行号
#grep -n:打印匹配行号
if [ -z "$lineNum" ]; then #-z 判断 变量的值,是否为空;找不到行号
echo "警告:学生学号不存在!无法修改~"
return
fi
name=$(sed -n "${lineNum}p" $Student_Score | cut -d "," -f 2)
#sed -n:只显示匹配处理的行(否则会输出所有)
#从行号找该行第2列值即姓名
echo "原成绩记录为:"
sed -n "${lineNum}p" $Student_Score
echo -n "请输入新的高数成绩:"
read newmath
echo -n "请输入新的英语成绩:"
read newenglish
echo -n "请输入新的物理成绩:"
read newphysics
echo -n "请输入新的政治成绩:"
read newpolitics
echo -n "请输入新的C语言成绩:"
read newcyuyan
total=$((newmath+newenglish+newphysics+newpolitics+newcyuyan))
avg=$(echo "scale=2; $total/5" | bc)
newInfo="$sid,$name,$newmath,$newenglish,$newphysics,$newpolitics,$newcyuyan,$total,$avg"
sed -i "${lineNum}s/.*/$newInfo/" $Student_Score
#使用sed命令将$newInfo的内容替换文件$Student_Score中第lineNum行的内容
echo "修改成功!"
echo -n "是否继续修改学生成绩信息(y/n):"
read choice
case $choice in
Y|y)
modify_Score_Info
;;
N|n)
echo -e"\n"
;;
*)
echo "无效选择!"
;;
esac
}
# 删除成绩函数
del_Score_Info() {
echo -n "请输入要删除的学生学号:"
read sid
lineNum=$(grep -n "$sid" $Student_Score | cut -d ":" -f 1)
if [ -z "$lineNum" ]; then
echo "警告:该学生学号不存在! 无法删除~"
return
fi
echo "原记录为:"
sed -n "${lineNum}p" $Student_Score
#p:打印
sed -i "${lineNum}d" $Student_Score
#d:删除
echo "删除成功!"
echo -n "是否继续删除学生成绩信息(y/n):"
read choice
case $choice in
Y|y)
del_Score_Info
;;
N|n)
echo -e"\n"
;;
*)
echo "无效选择!"
;;
esac
}
# 查看单个学生成绩
search_Score_Single_Info() {
echo -n "请输入要查询的学生学号:"
read sid
lineNum=$(grep -n "$sid" $Student_Score | cut -d ":" -f 1)
if [ -z "$lineNum" ]; then
echo "警告:学生学号不存在,请输入正确的学号~"
return
fi
echo -e "ID\t\t姓名\t高数\t英语\t物理\t政治\tC语言\t总分\t平均分"
sed -n "${lineNum}p" $Student_Score | awk -F',' '{
printf "%-16s%-12s%-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", $1, $2, $3, $4, $5, $6, $7, $8,$9}'
#awk就是把文件逐行的读入,awk -F ',' 以逗号为分隔符读入每列值
#%-12s表示左对齐输出,宽度为12,不够右补齐,多余则原样输出
echo -n "是否继续查看学生成绩(y/n):"
read choice
case $choice in
Y|y)
search_Score_Single_Info
;;
N|n)
echo -e"\n"
;;
*)
echo "无效选择!"
;;
esac
}
# 显示所有学生成绩,按指定科目排序
view_Score_Info() {
echo -e "------------------------------------------------------------"
echo -e "请选择要按哪一科成绩排序:"
echo -e "1. 高数"
echo -e "2. 英语"
echo -e "3. 物理"
echo -e "4. 政治"
echo -e "5. C语言"
echo -e "6. 总分"
read choice
case $choice in
1)
echo -e "学号\t\t姓名\t高数\t英语\t物理\t政治\tC语言\t总分\t平均分"
sort -t',' -k3,3 -r -n $Student_Score | awk -F',' '{
printf "%-16s%-12s%-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", $1, $2, $3, $4, $5, $6, $7, $8,$9}'
#-t :分隔符,-k3,3表示按照第三列进行排序,并且仅限于第三列,-n:按数字排,-r:逆序
;;
2)
echo -e "学号\t\t姓名\t高数\t英语\t物理\t政治\tC语言\t总分\t平均分"
sort -t',' -k4,4 -r -n $Student_Score | awk -F',' '{
printf "%-16s%-12s%-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", $1, $2, $3, $4, $5, $6, $7, $8,$9}'
;;
3)
echo -e "学号\t\t姓名\t高数\t英语\t物理\t政治\tC语言\t总分\t平均分"
sort -t',' -k5,5 -r -n $Student_Score | awk -F',' '{
printf "%-16s%-12s%-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", $1, $2, $3, $4, $5, $6, $7, $8,$9}'
;;
4)
echo -e "学号\t\t姓名\t高数\t英语\t物理\t政治\tC语言\t总分\t平均分"
sort -t',' -k6,6 -r -n $Student_Score | awk -F',' '{
printf "%-16s%-12s%-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", $1, $2, $3, $4, $5, $6, $7, $8,$9}'
;;
5)
echo -e "学号\t\t姓名\t高数\t英语\t物理\t政治\tC语言\t总分\t平均分"
sort -t',' -k7,7 -r -n $Student_Score | awk -F',' '{
printf "%-16s%-12s%-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", $1, $2, $3, $4, $5, $6, $7, $8,$9}'
;;
6)
echo -e "学号\t\t姓名\t高数\t英语\t物理\t政治\tC语言\t总分\t平均分"
sort -t',' -k8,8 -r -n $Student_Score | awk -F',' '{
printf "%-16s%-12s%-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", $1, $2, $3, $4, $5, $6, $7, $8,$9}'
;;
*)
echo "无效选择"
;;
esac
echo -e "------------------------------------------------------------"
echo -n "是否继续查看单科(或总分)排序信息(y/n):"
read choice
case $choice in
Y|y)
view_Score_Info
;;
N|n)
echo -e"\n"
;;
*)
echo "无效选择!"
;;
esac
}
# 查看成绩排名
rank_Viewer() {
echo -n "请输入要查询的排名(前几名):"
read num
echo -e "请选择要查看哪一科的排名:"
echo -e "1. 高数"
echo -e "2. 英语"
echo -e "3. 物理"
echo -e "4. 政治"
echo -e "5. C语言"
echo -e "6. 总分"
read choice
case $choice in
1)
echo -e "高数前$num名:"
echo -e "学号\t\t姓名\t分数"
sort -t',' -k3,3 -r -n $Student_Score | head -n $num | awk -F',' '{
printf "%-16s%-12s%-8s\n", $1, $2, $3}'
#head -n $num 表示显示前 $num 行的内容 awk 是一种文本处理工具,-F',' 表示以逗号作为字段分隔符
;;
2)
echo -e "英语前$num名:"
echo -e "学号\t\t姓名\t分数"
sort -t',' -k4,4 -r -n $Student_Score | head -n $num | awk -F',' '{
printf "%-16s%-12s%-8s\n", $1, $2, $4}'
;;
3)
echo -e "物理前$num名:"
echo -e "ID\t\t姓名\t分数"
sort -t',' -k5,5 -r -n $Student_Score | head -n $num | awk -F',' '{
printf "%-16s%-12s%-8s\n", $1, $2, $5}'
;;
4)
echo -e "政治前$num名:"
echo -e "学号\t\t姓名\t分数"
sort -t',' -k6,6 -r -n $Student_Score | head -n $num | awk -F',' '{
printf "%-16s%-12s%-8s\n", $1, $2, $6}'
;;
5)
echo -e "C语言前$num名:"
echo -e "学号\t\t姓名\t分数"
sort -t',' -k7,7 -r -n $Student_Score | head -n $num | awk -F',' '{
printf "%-16s%-12s%-8s\n", $1, $2, $7}'
;;
6)
echo -e "总分前$num名:"
echo -e "学号\t\t姓名\t分数"
sort -t',' -k8,8 -r -n $Student_Score | head -n $num | awk -F',' '{
printf "%-16s%-12s%-8s\n", $1, $2, $8}'
;;
*)
echo "无效选择"
;;
esac
echo "------------------------------------------------------------"
echo -n "是否继续查看单科(或总分)排名(y/n):"
read choice
case $choice in
Y|y)
rank_Viewer
;;
N|n)
echo -e"\n"
;;
*)
echo "无效选择!"
;;
esac
}
# 主程序
while true; do
Student_Score_page
read choice
case $choice in
1)
add_Score_Info
;;
2)
modify_Score_Info
;;
3)
del_Score_Info
;;
4)
search_Score_Single_Info
;;
5)
view_Score_Info
;;
6)
rank_Viewer
;;
0)
echo "bye! 欢迎下次使用~"
break
;;
*)
echo "功能选择错误,请重新输入!"
;;
esac
done