Shell 循环结构

2021-09-21 17:28:04
admin
2334
最后编辑:admin 于 2021-09-26 10:25:40

for-in 循环遍历列表

Shell 中 for-in 循环结构如下,将列表中的值依次赋给变量,去执行 do 后面的语句,直到所有的值都执行了一遍:

for 变量名 in 列表
do
    语句
    ……
done

do 也可以和 for-in 写在同一行,须用分号 ; 隔开,所以上面循环结构与下面同效:

for 变量名 in 列表; do
    语句
    ……
done

列表中的每个值用空格分隔开,逐个赋给变量,并执行下面的循环体。

如果某个值中有空格,则必须将该值用双引号""引起来(引号不会作为值的一部分)。

如果某个值中有引号,则必须用 \ 进行转义。

在最后一次迭代后,变量的值会在脚本的剩余部分一直保持有效,即它会一直保持最后一次迭代的值(除非你修改了它)。

实例:

#!/bin/bash
for num in 1 2 3 4 5 6 7
do 
  echo $num
done

执行结果:

$ ./test.sh    
1
2
3
4
5
6
7

字段分隔符

其实,列表中的多个值除了用上面提到的空格分隔,默认情况下,bash shell 会将下列字符当作分隔符:

    • 空格

    • 制表符

    • 换行符

当shell在数据中看到了这些字符中的任意一个,它就会认为这是列表中一个新数据的开始。

上面的字段分隔符是环境变量IFS的默认值,如果你想在某个地方修改它,比如想使shell只能识别换行符,之后忽略这次修改,在脚本的其他地方继续沿用IFS的默认值, 你就可以这样做:

IFS.OLD=$IFS
IFS=$'\n'
<在代码中使用新的IFS值>
IFS=$IFS.OLD

这就保证了在脚本的后续操作中使用的是IFS的默认值。事实上,我们还可以根据具体的应用场景,修改IFS的值以达到想要的目的。

指定列表中的值

Shell 支持通过以下几种不同的方法指定列表中的值:

1. 列表可以是一些现定义的数字或字符串,元素用空格分隔开。

for num in 1 2 3 4 5 6 7 8 9 10
do
    echo $num
done

列表中连续的数字也可以使用范围来表示,例如 1~10 数字可以直接写成 {1..10}

2. 从命令获取列表。例如像 ls 等会输出一个列表的命令:

for file in $(ls)

3. 从变量读取列表。

list="a b c d e f g"
for letter in $list
do
  echo $letter
done

for循环遍历数组:

for var in ${array[*]}
do
    语句
    ……
done

4. 用通配符 * 遍历目录中的文件。

在 Linux 系统中,一切皆为文件。

for file in /data/*
do
    if [ -d "$file" ]          #应对文件目录中包含空格,所以这里$file用双引号圈起来
    then
        echo "$file is a directory."
    elif [-f "$file"]
    then
        echo "$file is a file."
    fi
done

如果没有列表,Shell将从命令行获取参数列表,所以作用等同于$*作为列表(Shell中, $* 可以返回命令行中的参数列表):

      for variable 等同于 for variable in $*

类C风格的循环

学习过其他编程语言的小伙伴,应该对于类C风格的 for 循环结构更熟悉。Shell 也支持如下类C风格的循环结构:

for ((i=1; i<10; i++))  
do
    echo $i
done

注:

  • for 后面跟的是双括号 (( ));

  • 循环体依旧是在 do 与 done 之间;

until 直到型循环

类似于其他编程语言里的直到型循环 do-while。Shell 的 until 循环结构如下:

until [ 条件测试 ]
do
    语句
    ……
done

条件测试的判断为假时,执行循环体;直到为真时,才结束并退出until循环结构。

条件测试要放在方括号之间,并且左右要有空格。

实例:

#!/bin/bash
a=0
until [ $a = 100 ]; do
  echo $a
  a=$[ $a + 10 ]
done

执行结果:

$ ./test.sh    
0
10
20
30
40
50
60
70
80
90

while 当型循环

Shell 中 while 循环结构如下:

while 条件测试
do
    语句
    ……
done

while循环会在当测试条件不成立时停止并退出循环。

注:循环体中,一定不要漏掉循环变量的改变!否则会陷入无限循环。

与其他编程语言类似,Shell 中也可以在循环体内使用 break 和 continue 控制循环执行:

  • break   #立即终止并退出循环;

  • continue  #跳过本次循环中剩余的语句,直接继续执行下一次循环;

处理循环的输出

在shell脚本中,可以对循环的输出使用管道或重定向,这通过在done后面加一个处理命令来实现。

for file in /data/*
do
    if [ -d "$file" ]          
    then
        echo "$file is a directory."
    elif [-f "$file"]
    then
        echo "$file is a file."
    fi
done > output.txt

shell 会将 for 循环的结果重定向到文件 output.txt 中,而不是显示在屏幕上。