一道有意思的 shell 脚本面试题

一道有意思的 shell 脚本面试题

前几天面试的时候,有一道 shell 脚本题,让我印象深刻,倒不是多难,但是对于我来说,有点不太简单,回去的路上,我苦思冥想,也想不出来思路,题目大致是这样的:

在这里插入图片描述
有这么一个表,内容大概是这样,计算每个人的总成绩。

我回去之后,找了很多资料,需要用到 awk 这个命令,但是这个命令我实在不熟啊,于是请教我的朋友,他给我提供了两个思路:

思路一、

将每行的最后一列的成绩拿出来,保存到每个不同的变量上,然后需要计算的时候直接相加就可以了。
代码如下:

ax=`cat test.log |grep a|grep x|awk '{pring $3}'`
bx=`cat test.log |grep b|grep x|awk '{pring $3}'`
cx=`cat test.log |grep c|grep x|awk '{pring $3}'`
ay=`cat test.log |grep a|grep y|awk '{pring $3}'`
by=`cat test.log |grep b|grep y|awk '{pring $3}'`
cy=`cat test.log |grep c|grep y|awk '{pring $3}'`
xm=$($ax+$ay)
xh=$($bx+$by)
xb=$($cx+$cy)
echo '小明的总成绩为:'$xm
echo '小红的总成绩为:'$xh
echo '小白的总成绩为:'$xb

但是我想到,如果是这样的话,就太固定了,但凡随便加上一行,这个脚本就行不通了,于是有了思路2

思路二、

使用循环,定义一个记录行数的变量 i ,还有各自的人物变量 xm(小明)、xh(小红)、xb(小白) ,每次读取一行,使 i1,然后将最后一列取出来,赋值给各自的人物变量,当循环到第三行,此时 i=3,赋值完成后, 将 i 置为 0,这时再次进入循环,第四行的数据还是小明的,依次类推,然后继续叠加,最后计算一下结果就可以了。
代码如下:

xm=0
xh=0
xb=0
i=0
cat test.log |while read line
do
((i++))
z=`echo $line|awk '{print $3}'`
if [ i=1 ]
then
xm=$((xm+z))
elif [ i=2 ]
then
xh=$((xh+z))
elif [ i=3 ]
then
xb=$((xb+z))
((i=0))
fi
done
echo '小明的总分是:'$xm
echo '小红的总分是:'$xh
echo '小白的总分是:'$xb

但是我想到,这样的话还是有点固定,如果人物位置变化一下,或者在加上一个人的话,那结果不就乱了么?

不过如果单纯解题的话,这两个思路还是没有任何问题的,还是得学习一下。

但是,我就比较较真,我在想,有没有比较完美的解题思路呢?
于是我开始查资料,学习、了解 awk 这个命令,就有了这版在我认为可以满足要求的思路:

思路三、

1、先将每行的第一列取出来,就是人名,因为要计算人物的总成绩嘛,所以不用考虑科目是什么
2、然后把结果赋值给一个变量,但是如果将 awk 结果直接赋值的话,是一个字符串,不是我想要的数组,所以需要进行分割
3、将分割的结果赋值给一个新的数组变量,但是由于人物有重复的,所以需要去重,想法就是对新数组进行循环,把重复的数据删除,那剩下的就是不重复的
4、使用 awk 命令,根据去重后的人名,计算这个人所有成绩的和,然后输出

list_old=`awk '{a=a$1" "};END {print a}' test.txt`
array=(${list_old// / })
array_len=${#array[*]}
for ((i=0;i<$array_len;i++))
do
    for ((j=$array_len-1;j>i;j--))
    do
        if [[ ${array[i]} = ${array[j]} ]]
        then
                unset array[i]
        fi
    done
done

for x in ${array[*]}
do
	result=`awk '/'$x'/ {sum += $3};END {print sum}' test.txt`
	echo $x'的成绩是:'$result
done

这一套是我目前能想到的最好的解决办法,如果重新加上一个人,或者把顺序打乱,结果都是没问题的

如果各位小伙伴们还有更好的办法,烦请不吝赐教,3Q!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

很简单_

点个赞在走呗 ~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值