15.1.1 带列表的for循环

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


  1. for VARIABLE in (list)

  2. do

  3. command

  4. done


下面的例子可循环打印出John喜爱的水果,每一次循环,变量FRUIT都被赋予了一个特定的值:由于列表中一共有4个元素,所以整个循环就会执行4次,每次循环变量FRUIT就依次被赋予一个列表中的值,所以第一次循环时FRUIT为apple,第二次为orange,第三次为banana,第四次为pear,执行到这里,将会随着列表的结束而停止循环体。一旦结束循环,脚本又会继续执行done后面的内容,本例中就是打印“No more fruits”。


  1. [root@localhost ~]# cat fruit01.sh

  2. #!/bin/bash

  3. for FRUIT in apple orange banana pear

  4. do

  5. echo "$FRUIT is John's favorite"

  6. Done

  7. echo "No more fruits"

  8. #

  9. 运行结果

  10. [root@localhost ~]# bash fruit.sh

  11. apple is John's favorite

  12. orange is John's favorite

  13. banana is John's favorite

  14. pear is John's favorite

  15. No more fruits


上面脚本的写法并不是最好的,因为一旦列表元素改变了,你就不得不去改相应的for循环语句块。好的习惯是将列表定义为一个变量,然后在for中使用该变量。按照这种方法可以将上面的脚本修改成下面的形式:


  1. [root@localhost ~]# cat fruit02.sh

  2. #!/bin/bash

  3. #

  4. 将列表定义到一个变量中,以后有任何修改只需要修改该变量即可

  5. fruits="apple orange banana pear"

  6. for FRUIT in ${fruits}

  7. do

  8. echo "$FRUIT is John's favorite"

  9. done

  10. echo "No more fruits"


如果列表是数字,常规的方法是使用列表列出所有可能的数值,for循环会遍历所有列出的值。下面的脚本会循环5次并打印内容。


  1. [root@localhost ~]# cat for_list01.sh

  2. #!/bin/bash

  3. for VAR in 1 2 3 4 5

  4. do

  5. echo "Loop $VAR times"

  6. done

  7. #

  8. 执行结果

  9. [root@localhost ~]# bash for_list01.sh

  10. Loop 1 times

  11. Loop 2 times

  12. Loop 3 times

  13. Loop 4 times

  14. Loop 5 times


如果只是少数的几个数字还是比较方便一一枚举出来的,但是如果是1到100,这么写就不实际了,Shell提供了用于计数的方式,比如说上例中1到5可以用{1..5}表示。所以脚本可以改写成下面的格式,运行结果和之前一致。


  1. [root@localhost ~]# cat for_list02.sh

  2. #!/bin/bash

  3. for VAR in {1..5}

  4. do

  5. echo "Loop $VAR times"

  6. done


还可以使用seq命令结合命令替换的方式生成列表,下面的例子可以针对1到100的求和进行计算,其中的命令替换部分还可以使用$()代替。


  1. [root@localhost ~]# cat for_list03.sh

  2. #!/bin/bash

  3. sum=0

  4. for VAR in `seq 1 100`

  5. #for VAR in $(seq 1 100)

  6. do

  7. let "sum+=VAR"

  8. done

  9. echo "Total: $sum"

  10. #

  11. 运行结果

  12. [root@localhost ~]# bash for_list03.sh

  13. Total: 5050


下面是利用seq命令的“步长”计算1到100内的奇数和。


  1. [root@localhost ~]# cat for_list04.sh

  2. #!/bin/bash

  3. sum=0

  4. for VAR in $(seq 1 2 100)

  5. do

  6. let "sum+=VAR"

  7. done

  8. echo "Total: $sum"

  9. [root@localhost ~]# bash for_list04.sh

  10. Total: 2500


从上面的命令替换的例子可以看出,其实列表for循环中in后面的内容可以是任意命令的标准输出。下面的例子中,会利用ls的输出作为in的列表,并循环打印所有文件的属性。


  1. [root@localhost ~]# cat for_list05.sh

  2. #!/bin/bash

  3. for VAR in $(ls)

  4. do

  5. ls -l $VAR

  6. done