最近在看張昊寫的《linux shell 編程從入門到精通》,喜歡這本書的風格,簡單易懂,還帶一點幽默,讀起來有味。
剛好看完第8章的awk,老師要求完成個程序,因爲是初學,在不斷的翻書,找資料,然後嘗試後,簡易地實現了。
作業:學生成績管理程序
Ø 程序功能:要求實現4個功能,每個功能作爲一個函數
Ø 1.向文件中插入記錄
Ø 2.顯示文件中的每條記錄的每個字段值
Ø 3.從文件中修改指定學號的記錄
Ø 4.對學生成績進行統計(包括每個學生總成績;每個學科前十名和總成績前二十名統計)
tip:
構造三個類似數據庫的文本文件:
第一個爲學院信息文件,包含字段:
學院編號(唯一),學院名稱
第二個爲學生信息文件,包含字段:
學號(唯一),學生姓名,所在學院編號,說明(休學suspended,退學dropout)
第三個爲學生成績文件,包含字段:
學號(唯一),學生姓名,科目名稱,成績;說明(期考final,補考makeup)
說明:每個記錄佔一行;分隔符可以自己選定,建議用”,”; 編碼規則自己定;文件名自己定
////////////////////////////工程目錄//////////////////////////////////////////
///////////////////以下是StuInfoSysMan.sh腳本//////////////////////////////
#! /bin/bash
####### use: insert a record #######
####### param1: file path #######
####### param2: add record #######
function insert()
{
sed -i "$ a\\$2" $1
cat $1
}
####### param1: filepath #######
function print_file()
{
if [ "$1" = "CollegeInfo" ]
then
echo "----------- this is CollegeInfo-----------"
echo "CollegeId,CollegeName"
cat $1
elif [ "$1" = "StuInfo" ]
then
echo "------------this is StuInfo---------------"
echo "StuId,StuName,CollgeId"
cat $1
elif [ "$1" = "ScoreInfo" ]
then
echo "------------this is ScoreInfo-------------"
echo 'StuId,StuName,Subjects,Scores,note'
cat $1
else
echo "$1: no file found"
return
fi
}
######## param1: filepath #######
######## param2: a key ##########
######## param3: newRecord ######
function modify_record()
{
#sed -i "$2\/\s\/\.\*\/$3\/" $1 # syntax error
#sed -i '/1001/s/.*/1001,xiaobinge,1/' $1 # syntax error
#sed -i '/$2/s/.*/$3/' $1 # syntax error
sed -i '/'$2'/s/.*/'$3'/' $1 # syntax right
cat $1
return
}
function count_file()
{
echo "----------the top10 of C subject-------------------"
#awk -f reportTotalScore.awk ScoreInfo
awk -f reportTotalScore.awk ScoreInfo|sort -t, -k3 -nr | head -n10
echo "----------the top10 of C++ subject-----------------"
awk -f reportTotalScore.awk ScoreInfo |sort -t, -k4 -nr | head -n10
echo "----------the top10 of JAVA subject----------------"
awk -f reportTotalScore.awk ScoreInfo |sort -t, -k5 -nr | head -n10
echo "----------the top20 of totalScore subject----------"
awk -f reportTotalScore.awk ScoreInfo |sort -t, -k6 -nr | head -n20
}
# main
while [ 1 ]
do
echo "///////////////menu tip///////////////////"
echo "item-0: exit"
echo "item-1: call print_fie func"
echo "item-2: call insert func"
echo "item-3: call modify_record func"
echo "item-4: call count_file func"
echo "please input your item 0~4"
echo "//////////////////////////////////////////"
read item
if [ "$item" = "0" ]
then
break
elif [ "$item" = "1" ]
then
#------------test print func--------------
print_file CollegeInfo
print_file StuInfo
print_file ScoreInfo
elif [ "$item" = "2" ]
then
#------------test insert func-------------
echo "輸入要爲學生文件插入的新的一條記錄,格式:學號,姓名,學院代號,備註"
# insert StuInfo "1009,knuth,1,"
read newRecord
insert StuInfo $newRecord
elif [ "$item" = "3" ]
then
#------------test modify field func-------
# modify_record StuInfo 1001 "1001,xiaobingeeeeee,1"
echo "請輸入要爲學生文件修改的新的記錄key:"
read key
echo "請輸入要爲學生文件修改的新的記錄,格式:學號,姓名,學院代號"
read newRecord
modify_record StuInfo $key $newRecord
elif [ "$item" = "4" ]
then
#-------------test count func-------------
count_file
else
echo "please input 0~4 for item"
fi
done
//////////////////////以下是reportTotalScore.awk腳本////////////////////////////
BEGIN {
FS=","
print "stuID\tstuName\tC\tC++\tjava\ttotalScore\tnote"
};
{$6=$3+$4+$5}
{
printf "%s,%s,%s,%s,%s,%s,%s\n",$1,$2,$3,$4,$5,$6,$7
}
////////////////////////以下是運行結果///////////////////////////
1.1 執行菜單item1call print_fie func
2 從文件中修改指定學號的記錄
3.向文件中插入記錄
4 對學生成績進行統計(包括每個學生總成績;每個學科前十名和總成績前二十名統計)
執行結果 ,可以看到不同的課程的排序結果和總排序結果(由於爲了截圖等方便,數據沒有超過10個,但是不影響代碼降序排列的功能)
可以看到不同科目C,C++,JAVA和總成績都已經呈降序排列
因爲這本書讓我更加喜歡了shell ,不再那麼恐懼,不得不承認那奇怪的語法確實剛開始不太適應,但是慢慢卻覺得這樣設計也是有其合理性的,那就是短小精悍,簡簡單單的命令描述,替代高級語言的所需要一大堆的代碼,這樣能減小項目的大小。一條條命令就像留有好多不同接口,參數讓用戶調用的的“算法類”似的,而不用親自去寫些“算法類”了。發現適合自己的書,是令人開心的事情。