循环与判断一样,是编程语言的重要控制结构。Shell的循环有for、while和until三种。
1. for循环
Shell的for循环有两种形式,值表形式和算术表达式形式。
(1)值表形式
值表形式的一般格式为:
for 变量 in 值表 do 命令 done
如:
for animal in Dog Cat Pig Sheep do echo $animal done
in后面也可以是数组:
[peter@ibi98 shell]$ color=(red green blue) [peter@ibi98 shell]$ for i in ${color[@]};do echo $i;done red green blue [peter@ibi98 shell]$ for i in ${color[*]};do echo $i;done red green blue
上面我们用分号(;)代替换行符,把整个脚本写成一个命令行。日常的数据处理等简单任务可以这样在命令行中实现,比写成脚本文件执行更快更方便。
in后面还可以是命令的执行结果:
[peter@ibi98 for]$ ls animal.txt plant.txt [peter@ibi98 for]$ for i in `ls *.txt`;do echo $i;cat $i;echo;done animal.txt dog cat pig sheep plant.txt rose lily lotus orchid
命令ls *.txt是显示当前目录中所有后缀为txt的文件,使用反引号(``)可以引用该命令的执行结果。
下面的例子是利用seq命令生成数字序列,并用for循环输出。seq的用法是seq [起始数字] [步长] 终止数字。
[peter@ibi98 for]$ for i in `seq 1 2 10`;do echo "$i: $((i*10))";done 1: 10 3: 30 5: 50 7: 70 9: 90
使用大括号也可以表示数字范围,如:
[peter@ibi98 for]$ for i in {1..5};do echo $i;done 1 2 3 4 5
(2)算术表达式形式
其一般格式为:
for ((e1:e2:e3)) do 命令 done
其中,e1、e2和e3为算术表达式,如下面的例子:
[peter@ibi98 for]$ for ((i=0;i<5;i++));do echo $i;done 0 1 2 3 4
2. while循环
while循环的一般格式为:
while 测试条件 do 命令 done
while循环的测试条件和if是一样的。while循环的作用与for循环一样:
[peter@ibi98 for]$ cat flower rose Chinese rose Dragon flower [peter@ibi98 for]$ cat flower |while read i;do echo "Flower: $i";done Flower: rose Flower: Chinese rose Flower: Dragon flower
但当文本中有空格的时候,while和for循环的结果是不一样的,如上面的例子用for循环输出:
[peter@ibi98 for]$ for i in `cat flower`;do echo $i;done rose Chinese rose Dragon flower
观察发现,for循环把空格和换行都作为元素的分隔符,这是因为for循环默认的输入字段分隔符是环境变量IFS的内容(通常是空格、制表符和换行符)。这种输出结果有时并不是我们想要的,因此如果处理的文本行内有空白,最好使用while循环,利用read命令逐行读入循环变量。
3. until循环
until循环的一般格式与while循环类似:
until 测试条件 do 命令 done
但until在逻辑上与while相反,while当后面的条件成立时执行循环,而until当后面的条件成立时停止循环。如:
[peter@ibi98 for]$ i= [peter@ibi98 for]$ while [[ i -lt 5 ]];do ((i=i+1));echo $i;done 1 2 3 4 5 [peter@ibi98 for]$ i= [peter@ibi98 for]$ until [[ $i -ge 5 ]];do ((i=i+1));echo $i;done 1 2 3 4 5
一般情况下until循环都可改写为while循环。
4. 跳出循环
与其他语言类似,Shell提供了break和continue命令来跳出循环。
(1)break
break跳出所有循环,即终止执行后面所有的循环。如:
[peter@ibi98 for]$ while :;do ((i=i+1));test $i -gt 5 && break;echo $i;done 1 2 3 4 5
当i>5时,终止执行循环,因此只输出1至5。:命令的执行结果永远为真,如果没有break,该循环将永远执行下去。
(2)continue
continue跳出当前的一次循环,继续执行执行后面的循环。如:
[peter@ibi98 for]$ while [[ "$i" -lt 5 ]];do ((i=i+1));test $i -eq 3 && continue;echo $i;done 1 2 4 5
当i=3时,跳过该次循环,继续执行下一个循环,所以结果中没有3。