shell脚本--循环控制

shell编程基础(shell脚本学习笔记)

循环


​ 在Shell编程中,很多时候需要反复执行一条或一组命令,比如说连续打印10条“Hello World”—虽然说不借助于循环而是写10条echo "Hello World"也可以完成同样的工作,但如果是打印100条呢?这时候如果还是采用这种写法,可能会让你烦不胜烦,这时就不得不借助于循环了。Shell中的循环主要有for、while、until、select几种。

1. for循环

for循环是Shell中最常见的循环结构,根据书写习惯又分为列表for循环、不带列表的for循环以及类C的for循环。

(1)带列表的for循环

​ 带列表的for循环用于执行一定次数的循环(循环次数等于列表元素个数),其语法结构如下:

for VARIABLE in (list)
do
        command
done

​ 列表的形式多种,如果列表是数字,如果只是少数的几个数字还是比较方便一一枚举出来的,但是如果是1到100,这么写就不实际了,Shell提供了用于计数的方式,例如 :

[root@localhost ~]# cat list_number1.sh
#!/bin/bash
for VAR in {1..5}
do
     echo "Loop $VAR times"
done
# 或者
[root@localhost ~]# cat list_number2.sh
#!/bin/bash
sum=0
for VAR in `seq 1 100`
#for VAR in $(seq 1 100)
do
      let "sum+=VAR"
done
echo "Total: $sum"
#运行结果
[root@localhost ~]# bash list_number2.sh
Total: 5050

(2)不带列表的for循环

​ 不带列表的for循环的结构如下所示:

for VARIABLE
do
       command
done

使用不带列表的for循环时,需要在运行脚本时通过参数的方式给for循环传递变量值。

[root@localhost ~]# cat for_list1.sh
#!/bin/bash
for VARIABLE in $@
do
        echo-n $VARIABLE
done
#运行时传入参数
[root@localhost ~]# bash for_list1.sh 1 2 3
1 2 3

(3)类C的for循环

​ Shell支持类C的for循环。了解C语言或类C语言的读者一定会对(i=1; i<=10; i++)这样的结构十分熟悉,在Shell中其语法结构如下:

for ((expression1; expression2; expression3))
do
       command
done

2.while循环

和for循环一样,while循环也是一种运行前测试语句,相比for循环来说,其语法更为简单, 语法结构如下:

while expression
do
        command
done

首先while将测试expression的返回值,如果返回值为真则执行循环体,返回值为假将不执行循环。循环完成后进入下一次循环之前将再次测试。

​ 下面的示例使用类while循环,同时计算1到100的和以及1到100的奇数和。

[root@localhost ~]# cat while_sum.sh
#!/bin/bash
#sum01 用于计算1到100的和
#sum02 用于计算1到100的奇数和
sum01=0
sum02=0
i=1
j=1
while [[ "$i" -le "100" ]]
do
        let "sum01+=i"
        let "j=i%2" #变量j用来确定变量i的奇偶性,如是奇数则余为1
        if [[ $j -ne 0 ]]; then
               let "sum02+=i"
        fi
        let "i+=1"
done

echo "sum01=$sum01"
echo "sum02=$sum02"
#运行结果
[root@localhost ~]# bash while_sum.sh
sum01=5050
sum02=2500

按行读取文件是while一个非常经典的用法,常用于处理格式化数据。比如说下面的一个用于记录学生信息的文件(读者自行创建,内容如下)。

[root@localhost ~]# cat student_info.txt
John    30      Boy
Sue     28      Girl
Wang    25      Boy
Xu      23      Girl

​ 仔细观察这个文件的内容不难发现,第一列是姓名,第二列是年龄,第三列是性别。利用while可按行读取的特性,依次打印学生信息。

[root@localhost ~]# cat while_file.sh
#!/bin/bash
while read LINE
do
        NAME=`echo $LINE | awk '{print $1}'`
        AGE=`echo $LINE | awk '{print $2}'`
        Sex=`echo $LINE | awk '{print $3}'`
        echo "My name is $NAME,I'm $AGE years old,I'm a $Sex"
done < student_info.txt
#运行结果
[root@localhost ~]# bash while_file.sh
My name is John,I'm 30 years old,I'm a Boy
My name is Sue,I'm 28 years old,I'm a Girl
My name is Wang,I'm 25 years old,I'm a Boy
My name is Xu,I'm 23 years old,I'm a Girl

3.until循环

until循环也是运行前测试,但是until采用的是测试假值的方式,当测试结果为假时才继续执行循环体,直到测试为真时才停止循环。其语法如下:

until expression
do
       command
done

​ 下面的示例使用until同时计算1到100的和以及1到100的奇数和。

[root@localhost ~]# cat until_sum.sh
#!/bin/bash
sum01=0
sum02=0
i=1
until [[ $i-gt 100 ]]
do
       let "sum01+=i"
       let "j=i%2"
       if [[ $j-ne 0 ]]; then
             let "sum02+=i"
       fi
       let "i+=1"
done
echo $sum01
echo $sum02
#运行结果
[root@localhost ~]# bash until01.sh
5050
2500

4.select循环

select是一种菜单扩展循环方式,其语法和带列表的for循环非常类似,基本结构如下:

select MENU in (list)
do
       command
done

当程序运行到select语句时,会自动将列表中的所有元素生成为可用1、2、3等数选择的列表,并等待用户输入。用户输入并回车后,select可判断输入并执行后续命令。如果用户在等待输入的光标后直接按回车键,select将不会退出而是再次生成列表等待输入

​ 下面的例子使用select确认用户的输入并交由case处理,之后将根据不同输入执行不同代码段。代码中使用了“|”符,表示选择Saturday和Sunday的效果是一致的。

[root@localhost ~]# cat select_week.sh
#!/bin/bash
select DAY in Mon Tue Wed Thu Fri Sat Sun
do
        case $DAY in
        Mon) echo "Today is Monday";;
        Tue) echo "Today is Tuesday";;
        Wed) echo "Today is Wednesday";;
        Thu) echo "Today is Thursday";;
        Fri) echo "Today is Friday";;
        Sat|Sun) echo "You can have a rest today";;
        *) echo "Unknown input,exit now" && break;;
        esac
done
#运行结果
[root@localhost ~]# bash select_week.sh
1) Mon
2) Tue
3) Wed
4) Thu
5) Fri
6) Sat
7) Sun
#? 1
Today is Monday
#? 6
You can have a rest today
#? 7
You can have a rest today
#? 8
Unknown input,exit now

5.嵌套循环

​ 所谓嵌套循环指的是一个循环语句中的循环体是另外一个循环。前面讲到的for、while、until、select循环语句都可以使用嵌套循环。在嵌套循环中可以多层嵌套,但是要注意,过度的嵌套会让程序变得晦涩难懂,所以除了确实必要的情况下,不建议使用多层嵌套(三层以上的嵌套)

下面使用for的嵌套循环打印九九乘法表,这个经典的程序。

$ cat nesting1.sh
#!/bin/bash
for ((i=1; i<=9; i++))
do
        for ((j=1; j<=i; j++))
        do
                let "mult=$i*$j"
                echo -n "$j*$i=$mult "
        done
        echo
done

$ bash nesting1.sh
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81


6.循环控制

break语句

break用于终止当前整个循环体。一般情况下,break都是和if判断语句一起使用的,当if条件满足时使用break终止循环。

​ 我们可以使用break语句改写一下上面嵌套循环的程序(九九乘法表):

$ cat nesting2.sh
#!/bin/bash
for ((i=1; i<=9; i++))
do
        for ((j=1; j<=9; j++))
        do
                if [[ $j -le $i ]]; then  # j小于i输出
                        let "mult=$i*$j"
                        echo -n "$j*$i=$mult "
                else
                        break  # j如果大于i就停止
                fi
        done
        echo
done

$ bash nesting2.sh
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81

coutinue语句

continue语句用于结束当前循环转而进入下一次循环,与break不同的是continue并不会终止当前的整个循环体,它只是提前结束本次循环,而循环体还将继续执行;而break则会结束整个循环体。

我们以打印1到100之间的所有素数为例:

$ cat continue.sh
#!/bin/bash

for ((i=1; i<=100; i++))
do
        for ((j=2; j<(i/2)+1; j++))
        do
                if !(($i%$j)); then
                        continue 2
                        # 2代表调成两层循环
                fi
        done
        echo -n "$i "
done
echo

$ bash continue.sh
1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zhanjun.520

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值