【Linux编程】shell编程初步

一、实验目的

l 掌握基本的shell编程

二、实验内容

1. 目录/home/buyhorse1/records/linux2023Spring,保存了上课出勤的记录,每次上课进行2次点名,每天的2次点名只要出现1次就认定本次上课出勤1次。

(1)请统计每名学生出勤的次数。输出格式为:学生账号:次数。

(2)自己的出勤统计要求在最后一行输出。

2. 回文数是指其各位数字左右对称的整数,例如121,1001,92329等。编写一个程序,输入一个正整数n,打印从1‐n之间的回文数,并统计个数。

三、实验代码

1.统计上课出勤次数:2394.sh

1.#/bin/sh  
2.
3.#统计四月四号两个文件中,每个用户是否有出现,下同
4.cat ./20230404* > 2394.txt
5.awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u  > mid.txt
6.
7.cat ./20230411* > 2394.txt
8.awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u  >> mid.txt
9.
10.cat ./20230418* > 2394.txt
11.awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u  >> mid.txt
12.
13.cat ./20230423* > 2394.txt
14.awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u  >> mid.txt
15.
16.cat ./20230425* > 2394.txt
17.awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u  >> mid.txt
18.
19.cat ./20230509* > 2394.txt
20.awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u  >> mid.txt
21.
22.#根据上面六次统计,计算每名学生的出现次数,并根据学生序号排序
23.awk '{a[$1]++}END{for(i in a){print i": "a[i]}}' mid.txt | sort -k 1 | grep "stu" > 2394.txt
24.
25.#找出我的出勤次数,并将其放至最后
26.grep -v "stu2394" 2394.txt > final.txt
27.grep "stu2394" 2394.txt >> final.txt
28.
cat final.txt

2.打印回文数与其个数:exp3-2.sh

1.#!/bin/bash                                                                  
2.read -p "please input a number:" number
3.mod=1
4.#n为回文数的个数
5.n=0
6.for i in `seq 1 $number`
7.do
8.    #例如,i=123,则mod=100
9.    if [ $i -eq `expr $mod \* 10` ]
10.        then mod=`expr $mod \* 10`
11.    fi
12.
13.    mid_mod=$mod
14.    mid_i=$i
15.    #flag=1,表示i是回文数
16.    flag=1
17.    while [ 1 -eq 1 ]
18.    do
19.        #检查mid_i的最后一位与第一位是否相同
20.        if [ `expr $mid_i / $mid_mod` -ne `expr $mid_i % 10` ]
21.            then 
22.                flag=0
23.                break
24.        fi
25.
26.        #如果mid_i只剩2位或1位,则不再继续检查
27.        if [ $mid_mod -le 10 ]
28.            then break
29.        fi
30.
31.        #去掉mid_i的第一位与最后一位
32.        mid_i=`expr $mid_i % $mid_mod`
33.        mid_i=`expr $mid_i / 10`
34.        mid_mod=`expr $mid_mod / 100`
35.    done
36.
37.    if [ $flag -eq 1 ]
38.        then 
39.            echo "$i"
40.            n=`expr $n + 1`
41.    fi
42.done
echo "the number is $n"

四、实验分析与结果

1.统计上课出勤次数

由于每次上课进行2次点名,只要出现1次就认定本次上课出勤1次,我们需要对每天的两个文件两两进行统计。先将每天的两个文件合并成一个,然后统计这个文件中出现的账号,由于每名同学的账号是唯一且不可重复的,我们对账号进行去重操作,将结果存放至mid.txt文件中:

cat ./20230404* > 2394.txt

awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u > mid.txt

由此往后对每天的文件都进行相同的操作,最后叠加到mid.txt文件中:

cat ./20230411* > 2394.txt

awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u >> mid.txt

cat ./20230418* > 2394.txt

awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u >> mid.txt

cat ./20230423* > 2394.txt

awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u >> mid.txt

cat ./20230425* > 2394.txt

awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u >> mid.txt

cat ./20230509* > 2394.txt

awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt | sort -u >> mid.txt

经过上面的操作,我们可以保证mid.txt文件中存储着每节课出勤学生的账号,根据文件中账号的出现次数,可以统计出学生的总共出勤次数,并将根据学生序号排序的结果保存至2394.txt文件中:

awk '{a[$1]++}END{for(i in a){print i": "a[i]}}' mid.txt | sort -k 1 | grep "stu" > 2394.txt

在2394.txt文件中找到我的出勤次数,并将其放至最后

grep -v "stu2394" 2394.txt > final.txt

grep "stu2394" 2394.txt >> final.txt

最后输出出勤结果:

cat final.txt

中间略

2.打印回文数与其个数

编写一个程序,输入一个正整数n,打印从1‐n之间的回文数,并统计个数。

通过read命令输出提示语句并读取正整数n:

read -p "please input a number:" number

回文数的特征是最低位数与最高位数相同,并以此类推,所以我们只要每次比较最高位与最低位,若相同,则去掉最高位与最低位继续比较,直至余下一位或零位没比较即可。

在循环比较之前,我们首先需要确定数据的位数:

if [ $i -eq `expr $mod \* 10` ]

then mod=`expr $mod \* 10`

fi

确定了位数之后,我们开始循环比较。

设置标志位flag,flag=1表示是回文数,flag=0表示不是回文数。

首先,我们可以利用位数计算出数据的第一位与最后一位,并比较是否相同,若相同,则继续比较,否则,该数不是回文数:

if [ `expr $mid_i / $mid_mod` -ne `expr $mid_i % 10` ]

then

flag=0

        Break

fi

比较之后,如果当前比较的是剩余最后两位或一位,则比较结束:

if [ $mid_mod -le 10 ]

then break

fi

若不是,则去掉当前比较位(第一位与最后一位),并将该数的位数缩小两位:

mid_i=`expr $mid_i % $mid_mod`

mid_i=`expr $mid_i / 10`

mid_mod=`expr $mid_mod / 100`

循环比较结束后,查看该数是否是回文数,如果是,则将回文数的总个数加一:

if [ $flag -eq 1 ]

then

     echo "$i"

        n=`expr $n + 1`

fi

所有数比较完成后,输出回文数的总个数:

echo "the number is $n"

 中间略

六、遇到问题及解决方法

1.统计上课出勤次数

问题一:如何统计一个文件中账户出现的次数。

解决方法:通过使用awk命令结合数组与循环:awk '{a[$1]++}END{for(i in a){print i": "a[i]}}' mid.txt,其中,i为索引,a[i]是值;由于学生账户的唯一性,相同账户每出现一次,对应的值就加一,这个值即为对应的出勤次数。

问题二:如何使每天的2次点名只要出现1次就认定本次上课出勤1次。

解决方法:对每天的两个文件两两进行统计。先将每天的两个文件合并成一个。为了便于去重工作,只统计这个文件中出现的账号:awk '{a[$1]++}END{for(i in a){print i}}' 2394.txt。然后进行去重工作:sort -u

问题三:输出结果中出现了除学生账号外的其他账号。

解决方法:通过管道添加grep "stu"命令,以筛选出学生账号。

问题四:如何将自己的结果放至最后。

解决方法:通过grep -v命令先筛选出出了自己账号之外的账号,再通过grep "stu2394"命令将自己的出勤次数添加至文件尾。

2.打印回文数与其个数

问题一:如何计算数i的位数。

解决方法:由于我选择列出1-n个数一个一个比较的方法,可以设置一个变量mod=1,一旦发现数i增长到与10*mod相等的情况,mod就增长十倍,由此,mod可以作为数i的位数。

问题二:比较重要的问题是shell编程的代码格式问题,一旦稍不留意,便会报错。

解决方法:首先是中括号[]可以与旁边的字符空一格,留出空间。其次是计算问题需要利用`expr xxx`格式,并且用到的变量记得带$符号。

七、实验总结

通过本次实验,在不停地对代码进行修改与完善的过程中,我对shell编程中常用的命令与参数更加熟悉了,并且对shell编程中的代码格式问题有了更多的处理经验,收获颇丰。不过,要想对shell编程有更深层次的掌握,还需要经过进一步学习与大量的练习。

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值