15.1.1 带列表的for循环
带列表的for循环用于执行一定次数的循环(循环次数等于列表元素个数),其语法结构如下:
- for VARIABLE in (list)
do
command
done
下面的例子可循环打印出John喜爱的水果,每一次循环,变量FRUIT都被赋予了一个特定的值:由于列表中一共有4个元素,所以整个循环就会执行4次,每次循环变量FRUIT就依次被赋予一个列表中的值,所以第一次循环时FRUIT为apple,第二次为orange,第三次为banana,第四次为pear,执行到这里,将会随着列表的结束而停止循环体。一旦结束循环,脚本又会继续执行done后面的内容,本例中就是打印“No more fruits”。
- [root@localhost ~]# cat fruit01.sh
#!/bin/bash
for FRUIT in apple orange banana pear
do
echo "$FRUIT is John's favorite"
Done
echo "No more fruits"
#
运行结果
[root@localhost ~]# bash fruit.sh
apple is John's favorite
orange is John's favorite
banana is John's favorite
pear is John's favorite
No more fruits
上面脚本的写法并不是最好的,因为一旦列表元素改变了,你就不得不去改相应的for循环语句块。好的习惯是将列表定义为一个变量,然后在for中使用该变量。按照这种方法可以将上面的脚本修改成下面的形式:
- [root@localhost ~]# cat fruit02.sh
#!/bin/bash
#
将列表定义到一个变量中,以后有任何修改只需要修改该变量即可
fruits="apple orange banana pear"
for FRUIT in ${fruits}
do
echo "$FRUIT is John's favorite"
done
echo "No more fruits"
如果列表是数字,常规的方法是使用列表列出所有可能的数值,for循环会遍历所有列出的值。下面的脚本会循环5次并打印内容。
- [root@localhost ~]# cat for_list01.sh
#!/bin/bash
for VAR in 1 2 3 4 5
do
echo "Loop $VAR times"
done
#
执行结果
[root@localhost ~]# bash for_list01.sh
Loop 1 times
Loop 2 times
Loop 3 times
Loop 4 times
Loop 5 times
如果只是少数的几个数字还是比较方便一一枚举出来的,但是如果是1到100,这么写就不实际了,Shell提供了用于计数的方式,比如说上例中1到5可以用{1..5}表示。所以脚本可以改写成下面的格式,运行结果和之前一致。
- [root@localhost ~]# cat for_list02.sh
#!/bin/bash
for VAR in {1..5}
do
echo "Loop $VAR times"
done
还可以使用seq命令结合命令替换的方式生成列表,下面的例子可以针对1到100的求和进行计算,其中的命令替换部分还可以使用$()代替。
- [root@localhost ~]# cat for_list03.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 for_list03.sh
Total: 5050
下面是利用seq命令的“步长”计算1到100内的奇数和。
- [root@localhost ~]# cat for_list04.sh
#!/bin/bash
sum=0
for VAR in $(seq 1 2 100)
do
let "sum+=VAR"
done
echo "Total: $sum"
[root@localhost ~]# bash for_list04.sh
Total: 2500
从上面的命令替换的例子可以看出,其实列表for循环中in后面的内容可以是任意命令的标准输出。下面的例子中,会利用ls的输出作为in的列表,并循环打印所有文件的属性。
- [root@localhost ~]# cat for_list05.sh
#!/bin/bash
for VAR in $(ls)
do
ls -l $VAR
done