Linux(九) 之 shell编程

一. $变量的使用
study1.sh脚本代码如下:

#!/bash/bin
#打印adc这个变量,比如主进程定义一个变量: export abc=10
echo $abc
#打印第一个变量
echo $1
#打印第二个变量
echo $2
echo "--------"
# $#表示参数个数,打印参数个数
echo $#
# $*相当于java的list.toString(),获取以字符串返回所有参数元素
echo $*
# 相当于java的list.toArray(),返回以数组形式的所有参数元素
echo $@

程序结果:
这里写图片描述
这里写图片描述

$? 上一个命令的执行是否成功
展示参数列表:
$@ 独立参数
$* 当做整体

二. if,case条件判断
1.写一个成绩判断程序,当分数x不低于90,打印A,不低于80,打印B,不低于60,打印C,否则为D
这里写图片描述
if代码

if([ $1 -ge 90 ]);
then
    echo 'A';
elif([ $1 -ge 80 ]);
then
    echo 'B';
elif([ $1 -ge 60 ]);
then
    echo 'C';
else
    echo 'D';
fi 

2.写一个简易计算器,
比如:
输入参数3 + 5,输出8
输入参数11 \* 11,输出121
输入参数6 / 7,输出0
输入参数7 - 6,输出1

#!/bash/bin
var=$2
case $2 in
    +)
        var=$[$1+$3]
        ;;
    -)
        var=$[$1-$3]
        ;;
    /)
        var=$[$1/$3]
        ;;
    \*)
        var=$[$1*$3]
        ;;
    # *是一个通配概念,相当于java的default
    *)
        var=error
        ;;
esac
#判断是否为整数,如果是整数,r将为空
#获取var的值,截掉第一个负号,截掉所有数字,r剩下为非数字
r=`echo $var | sed "s/^-//gi" | sed "s/[0-9]//gi"`
[ -n "$r" ] && echo 错误 && exit 1
echo $var
exit 0

这里写图片描述

三. for,while循环语句

1.计算1到100以内所有能被11整除的整数的和(while实现)

#!/bash/bin
var=1
sum=0
#从1到100循环
while [ $var -le 100 ]
do
#取余
mod=$[$var%11]
#判断是否能被11整除
if([ $mod -eq 0 ])
then
#求和
sum=$[sum+var]
fi
var=$[var+1]
done
#打印和
echo $sum

2.给定一张成绩表,计算每个同学的平均成绩(for实现)
成绩表如下
vi student

name    java    hadoop  linux   sql
qwer    60      67      75      98
tyzx    97      87      90      76
moon    79      91      92      87
fly     37      45      66      100
sky     56      96      97      61
check   70      61      52      39

此题用到了awk,需要了解awk可以查看我的另一篇博客,里面举了一个例子,比较容易看懂http://blog.csdn.net/m0_37681914/article/details/70156370
系统学习awk的话,可以查看博客
http://www.cnblogs.com/repository/archive/2011/05/13/2045927.html
awk的强大之处在于对文本处理了,在这一点上丝毫不逊色于java中String类.

#!/bash/bin

#研究了一下,awk中的对if条件判断和shell中语法还是有很大的区别,for也有一点点,请读者小心哦!
awk '
BEGIN{print "统计结果如下\nname\tavg";}
{
    #统计成绩表  
    for(i=2;i<=NF;i++){
        #成绩表第一行,则为各课程
        if(NR==1)
            ind[i]=$i;
        #非第一行,则为成绩,score存入"课程名--该课程成绩和",stu存放学生成绩总分
        else{
            score[ind[i]]=score[ind[i]]+$i;
            stu[$1]=stu[$1]+$i;
        }
    };
    count=NF-1;
    #打印学生平均成绩
    if(NR!=1)
        print $1 "\t" stu[$1]/count;
}
#打印课程成绩平均成绩
END{print "--------------------\ncourse\tavg";total=NR-1; for(i in score) print i "\t" score[i]/total}
' \
student

这里写图片描述

四. 使用shell编程完成小程序
现在,我们可以开始做一做bash小程序了!
在赛码网有bash题,可以刷
http://exercise.acmcoder.com/online/online_judge_list_all?konwledgeId=134
例题:
这里写图片描述
这里写图片描述

接下来,我们自己练练手吧!
1.求约德尔测试
http://exercise.acmcoder.com/online/online_judge_ques?ques_id=1677&konwledgeId=134
这里写图片描述

编程的基本原则是从小点入手,本题的第一个小点,就是将第一列字符串转为010101011的二进制字符串,也就是字符串替换了,可以用sed,下面这张图是我一个一个测试的过程.
这里写图片描述

以上已经处理好字符串替换了,接下来应该思考匹配的问题了.

一开始我的思路是,首先统计有多少个数字a,将处理好的二进制串与输入的二进制串,做异或运算,将计算结果统计有r个1, 则 0的个数为b=a-r ; 最后b/a即可计算出结果.
相关测试如下:

    #模拟两个2进制数
   v1=2#10101101101
   v2=2#10101101110
   #异或运算,得到结果将为11,即两个位置有不同的数字
   v3=$[$v1^$v2]
   #按二进制打印(测试一下)
   echo "obase=2;$v3"|bc
   #统计有多少个1
   r=`echo "obase=2;$v3"|bc | sed "s/0//gi" | wc -c`
   #wc统计的时候包括了\n字符,需要减一
   r=$[$r-1]
   #统计原字符串有多少个字符
   a=`echo $v1 | wc -c`
   #统计的时候包含了2#,以及\n,需要减3
   a=$[$a-3]
   #计算有多少个相同的结果
   b=$[$a-$r]
   #计算最终结果
   echo "scale=2;$b/$a" | bc

这里写图片描述
结果是预计之中!
但是却忽略一个很严重的问题,就是,数字是有界限的,题目要求是不超过1000位,二进制数的极限大概是63位(我没有测试过)

好吧,还是得一个一个来比较字符,写循环吧!
把字符串接着修改一下:

echo 'hello 123 #@1' | sed "s/[a-z|0-9]/1/gi" | sed "s/[^1]/0/gi" | sed "s/\([0-1]\)/\1 /gi"

这里写图片描述

这样就好切割字符串了

#!/bash/bin
#读取两个字符串
read -a s1
read -a s2
#将两个字符串转换为0 1 0 1这种类型格式
s3=`echo $s1 | sed "s/[a-z|0-9]/1/gi" | sed "s/[^1]/0/gi" | sed "s/\([0-1]\)/\1 /gi"`
s4=`echo $s2 | sed "s/\([0-1]\)/\1 /gi"`
#echo $s3
#echo $s4
#将字符串切割成只存储单个字符的数组
arr1=($s3)
arr2=($s4)
#获取数组长度
a=${#arr1[@]}
#b用于记录相同的个数
b=0
#循环判断处理
#`seq 0 $[$a-1]`生成从0到$a-1个序列
#等价于java中for(int i=0;i<a;i++)
for i in `seq 0 $[$a-1]`;do
        #做对比判断
        if([ $[arr1[i]] -eq $[arr2[i]] ]);
        then
                b=$[$b+1];
        fi
done
#echo $b
#做最后的数值计算
b=$[$b*100]
result=$(echo "scale=2;$b/$a"|bc)
#按照格式调整结果
result=$result%
#输出结果
echo $result

这里写图片描述

这个代码已经比较接近理想结果了,只差最后一步了,就是四舍五入的问题了,比如0.666666应该输出成66.67%,而不是66.66%,当然,练到这里已经差不多了,后面有兴趣的同学可以做一做!
也可以参考:
http://blog.csdn.net/m0_37681914/article/details/78209177

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值