Linux shell编程之使用结构化命令 for循环 while循环 until循环 break命令 continue命令详解

目录

使用结构化命令 for循环 while循环 until循环 break命令 continue命令

①for循环

for循环基本格式:

读取值复杂的列表的内容

从变量读取列表:

从命令读取值:

更改字段分隔符:

用通配符读取目录

for循环实战——循环处理文件数据

②while循环

while循环的基本格式

③until循环

untill循环的基本格式:

         循环嵌套



 

前言

>>>学习循环的目的:了解如何重复一些过程和命令,即为循环执行一组命令直到某个特定条件

>>>与循环相关的命令主要包括:forwhileuntil

 


 

for循环

>>>bash shell提供了for命令,允许我们创建一个遍历一系列值的循环

>>>for循环便利的列表假定每个值都是用空格分割的,例如(1 "2" "贝")

>>>当某个值两边都是用了双引号时,shell不会将双引号当成值的一部分

 

for循环基本格式:

for val in list

do

commands

done

或者 for val in list;do commands;done (常用)

 

关于for循环基本格式说明:

>>>list参数,提供迭代要用到的一系列的值,可以是用空格隔开的字符串,也可以是产生值的命令

>>>for循坏结束后,变量val的值会保留最后一次赋予的值(变量在剩余shell脚本中依然生效)

          只有unset 变量,变量才会被清空

[bei@localhost test]$ cat for.sh
#!/bin/bash
for val in 0 7 5
do
    echo $val
done
echo "The last val:val=$val"
unset val
echo "After unset val:val=$val"
[bei@localhost test]$ bash for.sh
0
7
5
The last val:val=5
After unset val:val=

       执行完for循环  ,val仍然保留最后一次赋予的值"5",并且在剩余shell脚本中仍然生效,

       如果需要让变量val失效,用unset即可

>>>dodone之间可输入一条或多条shell命令,包括嵌套if语句

[bei@localhost test]$ cat for.sh
#!/bin/bash
count=1
for i in 59 60 99
do
    if [ $i -ge 60 ]                            #在for循环里嵌套了if语句
    then
        echo "Grade $count : $i"
    fi
    count=$[$count+1]
done
[bei@localhost test]$ bash for.sh
Grade 2 : 60
Grade 3 : 99

 

读取值复杂的列表的内容

问题:遍历列表中的值,存在空格或特殊字符

方法:>>>使用 \ 处理

           >>>使用双引号或单引号处理

案例

[bei@localhost test]$ cat for.sh
#!/bin/bash
for val in It's a lucky dog !
do
    echo $val
done
[bei@localhost test]$ bash for.sh
for.sh: line 2: unexpected EOF while looking for matching `''
for.sh: line 6: syntax error: unexpected end of file

>>>列表中存在特殊字符,会报错

>>>解决方法1:使用\处理

[bei@localhost test]$ cat for.sh
#!/bin/bash
for val in It\'s a lucky dog \!
do
    echo $val
done
[bei@localhost test]$ bash for.sh
It's
a
lucky
dog
!

>>>解决方法2:使用双引号或单引号处理(此方法不仅可以输出特殊字符,还可以输出存在空格的值)

>>>shell不会把最外层的引号当做值的一部分,里面的引号会被输出

[bei@localhost test]$ cat for.sh
#!/bin/bash
for val in "It's" a "lucky dog" "!"
do
    echo $val
done
[bei@localhost test]$ bash for.sh
It's
a
lucky dog                                        #使用引号输出含有空格的值
!

 

从变量读取列表:

>>>当列表较长,直接将列表放在for循环中,不美观,修改麻烦

>>>可以先将列表赋给某个变量,然后再去遍历变量中的值

案例:

[bei@localhost test]$ cat for.sh
#!/bin/bash
list="1 2 3 4 5"     #将列表赋予变量,然后遍历变量中的值,实现从变量读取列表的值
list=$list" 6 7"     #实现列表的拼接
for i in $list
do
    echo $i
done
[bei@localhost test]$ bash for.sh
1
2
3
4
5
6
7

 

从命令读取值:

使用方法

>>>file="xxx.txt"

>>>for I in `cat $file`                      #使用反引从命令读取值

案例

[bei@localhost test]$ cat txt
Guangdong Guangzhou
Guangdong Shenzhen
Guangdong Shantou
[bei@localhost test]$ cat for.sh
#!/bin/bash
list="./txt"               
for i in `cat $list`
do
    echo $i
done
[bei@localhost test]$ bash for.sh
Guangdong
Guangzhou
Guangdong
Shenzhen
Guangdong
Shantou

 

更改字段分隔符:

>>>上一个案例,从命令读取值时,txt文件中的内容,行中存在空格,一行中的内容会被分别输出,不会在同一行输出

可以通过修改分隔符的方式解决这个问题

什么是分隔符

>>>分隔符全称叫内部字段分隔符(internal field separator)

>>>通过环境变量IFS,定义了bash shell字段分隔符的一系列字符

     set |grep IFS

     IFS=$' \t\n'  

>>>默认情况下bash shell的字段分隔符:

     空格( )

     制表符(\t)

     换行符(\n)

>>>如何修改分隔符——可在shell脚本中临时修改IFS环境变量

[bei@localhost test]$ cat txt
Guangdong Guangzhou
Guangdong Shenzhen
Guangdong Shantou
[bei@localhost test]$ cat for.sh
#!/bin/bash
IFS_old=$IFS
IFS=$'\n'
file='txt'
for i in `cat $file`
do
    echo "$i"
done
IFS=$IFS_old
[bei@localhost test]$ bash for.sh
Guangdong Guangzhou
Guangdong Shenzhen
Guangdong Shantou

>>>当需要在脚本中临时修改IFS变量时,需要先将IFS的默认值保存,当临时IFS变量使用完后,再讲IFS恢复成默认值

>>>指定多个分隔符:

     IFS=$' \t\n:;"'          #将空格,制表符,换行符,分号,和双引号作为分隔符

 

用通配符读取目录

使用通配符/var/history遍历这个目录,并对目录下的文件进行判断是否为普通文件

[bei@localhost test]$ cat for.sh
#!/bin/bash
for i in /var/history/*
do
if [ -f "$i" ]
then
echo "$i is exist and is a file"
else
echo "$i is exist and is not a file"
fi
done
[bei@localhost test]$ bash for.sh
/var/history/bei-507.log is exist and is a file
/var/history/root-0.log is exist and is a file

 

for循环实战——循环处理文件数据

结合的技术:

>>>使用嵌套循环

>>>修改IFS环境变量

案例:处理/etc/passwd文件中的数据,要求逐行遍历/etc/passwd文件,并将IFS变量的值修改成冒号

[bei@localhost test]$ cat loop.sh 
#!/bin/bash
IFS_OLD=$IFS
IFS=$'\n'
for line in `cat /etc/passwd`
do
        echo "Vales in $line"
        IFS=:
        for value in $line
        do
                echo "$value"
        done
done
IFS=$IFS_OLD
[bei@localhost test]$ bash loop.sh 
Vales in root:x:0:0:root:/root:/bin/bash
root
x
0
0
root
/root
/bin/bash
Vales in bin:x:1:1:bin:/bin:/sbin/nologin
bin
x
1
1	
bin
/bin
/sbin/nologin
Vales in daemon:x:2:2:daemon:/sbin:/sbin/nologin
daemon
x
2
2
daemon
/sbin
/sbin/nologin
......

 

 


 

while循环

>>>可以简单理解,while命令是if-then语句和for循环的混杂体

>>>while命令允许我们定义一个要测试的命令,我们定义的命令若返回的退出状态码为0,就会循环执行一组命令

>>>只要测试条件中的退出状态码一直为0,while命令后面那部分代码就会一直执行,
直到测试条件中的test命令返回的退出状态码不为0,while命令就会终止执行命令

 

while循环的基本格式

while test command   #测试命令退出状态码是0,就会去执行命令other commands

do

other commands

done

说明:

>>>while命令的关键是指定的test command返回的退出状态码要随着循环的执行而变化

>>>如果test command的退出状态码没有变化

若一直是0,则会产生一个死循环,other commands会一直被执行

若一直是非0,则other commands一直不会被执行

>>>可以在done后面追加[>> file],会将循环的结果输出重定向到某个文件

举例:

[bei@localhost test]$ cat ./txt
[bei@localhost test]$ cat while.sh
#!/bin/bash
val=1
while [ $val -le 3 ]
do
        echo "$val"
        val=$[ $val + 1 ]
done >> ./txt
[bei@localhost test]$ bash while.sh
[bei@localhost test]$ cat ./txt
1
2
3

 

当有多个测试条件时,以最后一个测试条件的退出状态码为准

while test command1 

test command2

test command3 

…….

done

说明

>>>此while循环以test command3的退出状态码为准

>>>test command1和test command2不会影响循环的跳转

 


 

until循环

>>>until命令和while命令的工作方式,是完全相反的

>>>untile命令允许我们定义一个要测试的命令,我们定义的命令若返回的退出状态码为非0,就会循环执行一组命令

>>>只要测试条件中的退出状态码一直为非0,until命令后面那部分代码就会一直执行,
直到测试条件中的test命令返回的退出状态码为0,until命令就会终止执行命令

>>>通俗理解:直到until中的测试条件成立,until循环才会停止

 

untill循环的基本格式:

until test command                        #测试命令退出状态码是非0,就会去执行命令other commands

do

other commands

done

 

举例

[bei@localhost test]$ cat until.sh
#!/bin/bash
val=8
until [ $val -gt 10 ]
do
    echo "$val" 
    val=$[ $val + 1 ]
done
[bei@localhost test]$ bash until.sh
8
9
10

说明:

当val=8时,test命令返回退出状态码为非0,until循环执行do后面的命令

当val=9时,test命令返回退出状态码为非0,until循环执行do后面的命令

当val=10时,test命令返回退出状态码为非0,until循环执行do后面的命令

当val=11时,test命令返回退出状态码为0,until循环不执行后面的命令,循环停止

 


 

循环嵌套

何为嵌套循环

>>>循环语句可以在循环内部使用任何类型的命令,当循环内使用的是其他循环命令时,这种称为嵌套循环

>>>嵌套层次越多,时间复杂度越大,一般来说时间复杂度是乘积关系

案例:

[bei@localhost test]$ cat nested.sh
#!/bin/bash
for (( a=1;a<4;a++ ))
do
    echo "outside loop : $a"
    for (( b=1;b<4;b++ ))
    do
        echo "inside loop : $b"
    done
done
[bei@localhost test]$ bash nested.sh
outside loop : 1
inside loop : 1
inside loop : 2
inside loop : 3
outside loop : 2
inside loop : 1
inside loop : 2
inside loop : 3
outside loop : 3
inside loop : 1
inside loop : 2
inside loop : 3

案例:

[bei@localhost test]$ cat nested.sh
#!/bin/bash
a=1
while [ $a -le 3 ]
do
        b=1
        echo "ouside loop : $a"
        until [ $b -ge 3 ]
        do
                echo "  inside loop : $b"
                b=$[$b+1]
        done
        a=$[$a+1]
done
[bei@localhost test]$ bash nested.sh
ouside loop : 1
        inside loop : 1
        inside loop : 2
ouside loop : 2
        inside loop : 1
        inside loop : 2
ouside loop : 3
        inside loop : 1
        inside loop : 2

 


 

④控制循环

>>>为何需要控制循环?

当循环启动时,在不对循环进行控制情况下,就必须等待循环迭代完成后循环才能终止

>>>如何控制循环?

两个命令可以帮我们控制循环内部的情况: break命令continue命令

 

break命令

>>>退出进行中的循环(包括for循环,while循环和until循环)

案例

[bei@localhost test]$ cat break.sh
#!/bin/bash
for i in 1 2 3 4 5
do
    if [ $i -le 3 ]
    then
        echo "$i"
    else
        echo "breaking"
        break
    fi
done
[bei@localhost test]$ bash break.sh
1
2
3
breaking

说明:在for循环,当满足if-then条件时,不执行break命令
          当不满足条件时,执行break命令,跳出正在处理的循环,即for循环

 

>>>对于嵌套循环,只会跳出和break最接近的循环,不会跳出外面的循环

案例

[bei@localhost test]$ cat break.sh
#!/bin/bash
for((a=1;a<4;a++))
do
        echo "a=$a"
        for((b=1;b<4;b++))
        do
                if [ $b -lt 3 ]
                then
                        echo "  b=$b"
                else
                        echo "breaking"
                        break
                fi
        done
done
[bei@localhost test]$ bash break.sh
a=1
  b=1
  b=2
breaking
a=2
  b=1
  b=2
breaking
a=3
  b=1
  b=2
breaking

说明:break命令只会跳出最接近它的那一层循环,而不会影响外部的循环

 

>>>对于嵌套循环,若需要停止外部循环,可以使用参数值 break n 即跳出n层循环

其中的n表示跳出循环的层级,默认情况下n的值为1,即为跳出当前循环

案例

[bei@localhost test]$ cat break.sh
#!/bin/bash
for((a=1;a<4;a++))
do
        echo "a=$a"
        for((b=1;b<4;b++))
        do
                if [ $b -lt 3 ]
                then
                        echo "  b=$b"
                else
                        echo "breaking"
                        break 2
                fi
        done
done
[bei@localhost test]$ bash break.sh
a=1
  b=1
  b=2
breaking

说明:break命令的2意味着它是跳出两层循环,即外面那层循环也停止了

 

continue命令

>>>只会跳过这一次循环后面部分代码,但并不完全终止整个循环

案例

[bei@localhost test]$ cat continue.sh
#!/bin/bash
for((a=1;a<=2;a++))
do
        echo "a=$a"
        for((b=1;b<=3;b++))
        do
                if [ $b -ne 2 ]
                then
                        echo "  b=$b"
                else
                        continue
                        echo "command1"
                fi
                echo "command2"
        done
done
[bei@localhost test]$ bash continue.sh
a=1
  b=1
command2
  b=3
command2
a=2
  b=1
command2
  b=3
command2

说明:当b=1时,正常输出

  当b=2时,执行continue命令,跳过这一次循环后面部分命令,包括command1和command2
                   但for循环未停止

  当b=3时,由于循环未停止,正常输出

 

 


 

说明:

>>>以上内容是本人学习的总结

>>>如还有错误,请留言,指正

>>>亦可分享自己的想法,互相学习

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值