除了 while 循环和 until 循环,Shell 脚本还提供了 for 循环,它更加灵活易用,更加简洁明了。Shell for 循环有两种使用形式,下面咱们逐一讲解。html
C语言风格的 for 循环正则表达式
C语言风格的 for 循环的用法以下:bash
for((exp1; exp2; exp3))
do
statements
doneide
几点说明:url
exp一、exp二、exp3 是三个表达式,其中 exp2 是判断条件,for 循环根据 exp2 的结果来决定是否继续下一次循环;
statements 是循环体语句,能够有一条,也能够有多条;
do 和 done 是 Shell 中的关键字。spa
它的运行过程为:
1) 先执行 exp1。htm
2) 再执行 exp2,若是它的判断结果是成立的,则执行循环体中的语句,不然结束整个 for 循环。blog
3) 执行完循环体后再执行 exp3。element
4) 重复执行步骤 2) 和 3),直到 exp2 的判断结果不成立,就结束循环。字符串
上面的步骤中,2) 和 3) 合并在一块儿算做一次循环,会重复执行,for 语句的主要做用就是不断执行步骤 2) 和 3)。
exp1 仅在第一次循环时执行,之后都不会再执行,能够认为这是一个初始化语句。exp2 通常是一个关系表达式,决定了是否还要继续下次循环,称为“循环条件”。exp3 不少状况下是一个带有自增或自减运算的表达式,以使循环条件逐渐变得“不成立”。
for 循环的执行过程可用下图表示:
下面咱们给出一个实际的例子,计算从 1 加到 100 的和。
#!/bin/bash
sum=0
for ((i=1; i<=100; i++))
do
((sum += i))
done
echo "The sum is: $sum"
运行结果:
The sum is: 5050
代码分析:
1) 执行到 for 语句时,先给变量 i 赋值为 1,而后判断 i<=100 是否成立;由于此时 i=1,因此 i<=100 成立。接下来会执行循环体中的语句,等循环体执行结束后(sum 的值为1),再计算 i++。
2) 第二次循环时,i 的值为2,i<=100 成立,继续执行循环体。循环体执行结束后(sum的值为3),再计算 i++。
3) 重复执行步骤 2),直到第 101 次循环,此时 i 的值为 101,i<=100 再也不成立,因此结束循环。
由此咱们能够总结出 for 循环的通常形式为:
for(( 初始化语句; 判断条件; 自增或自减 ))
do
statements
done
for 循环中的三个表达式
for 循环中的 exp1(初始化语句)、exp2(判断条件)和 exp3(自增或自减)都是可选项,均可以省略(但分号;必须保留)。
1) 修改“从 1 加到 100 的和”的代码,省略 exp1:
#!/bin/bash
sum=0
i=1
for ((; i<=100; i++))
do
((sum += i))
done
echo "The sum is: $sum
"
能够看到,将i=1移到了 for 循环的外面。
2) 省略 exp2,就没有了判断条件,若是不做其余处理就会成为死循环,咱们能够在循环体内部使用 break 关键字强制结束循环:
#!/bin/bash
sum=0
for ((i=1; ; i++))
do
if(( i>100 )); then
break
fi
((sum += i))
done
echo "The sum is: $sum"
break 是 Shell 中的关键字,专门用来结束循环,后续章节还会深刻讲解。
3) 省略了 exp3,就不会修改 exp2 中的变量,这时可在循环体中加入修改变量的语句。例如:
#!/bin/bash
sum=0
for ((i=1; i<=100; ))
do
((sum += i))
((i++))
done
echo "The sum is: $sum"
4) 最后给你们看一个更加极端的例子,同时省略三个表达式:
#!/bin/bash
sum=0
i=0
for (( ; ; ))
do
if(( i>100 )); then
break
fi
((sum += i))
((i++))
done
echo "The sum is: $sum"
这种写法并无什么实际意义,仅仅是为了给你们作演示。
Python 风格的 for in 循环
Python 风格的 for in 循环的用法以下:
for variable in value_list
do
statements
done
variable 表示变量,value_list 表示取值列表,in 是 Shell 中的关键字。
in value_list 部分能够省略,省略后的效果至关于 in $@,本文末尾的「value_list 使用特殊变量」将会详细讲解。
每次循环都会从 value_list 中取出一个值赋给变量 variable,而后进入循环体(do 和 done 之间的部分),执行循环体中的 statements。直到取完 value_list 中的全部值,循环就结束了。
Shell for in 循环举例:
#!/bin/bash
sum=0
for n in 1 2 3 4 5 6
do
echo $n
((sum+=n))
done
echo "The sum is "$sum
运行结果:
1
2
3
4
5
6
The sum is 21
对 value_list 的说明
取值列表 value_list 的形式有多种,你能够直接给出具体的值,也能够给出一个范围,还可使用命令产生的结果,甚至使用通配符,下面咱们一一讲解。
1) 直接给出具体的值
能够在 in 关键字后面直接给出具体的值,多个值之间以空格分隔,好比1 2 3 4 五、"abc" "390" "tom"等。
上面的代码中用一组数字做为取值列表,下面咱们再演示一下用一组字符串做为取值列表:
#!/bin/bash
for i in "abc" "123" "qwe" "我爱你"
do
echo $i
done
运行结果:
abc
123
qwe
我爱你
2) 给出一个取值范围
给出一个取值范围的具体格式为:
{start..end}
start 表示起始值,end 表示终止值;注意中间用两个点号相连,而不是三个点号。根据笔者的实测,这种形式只支持数字和字母。
例如,计算从 1 加到 100 的和:
#!/bin/bash
sum=0
for n in {1..100}
do
((sum+=n))
done
echo $sum
运行结果:
5050
再如,输出从 A 到 z 之间的全部字符:
#!/bin/bash
for c in {A..z}
do
printf "%c" $c
done
输出结果:
ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz
能够发现,Shell 是根据 ASCII 码表来输出的。
3) 使用命令的执行结果
使用反引号``或者$()均可以取得命令的执行结果,咱们在《Shell变量》一节中已经进行了详细讲解,并对比了二者的优缺点。本节咱们使用$()这种形式,由于它不容易产生混淆。
例如,计算从 1 到 100 之间全部偶数的和:
#!/bin/bash
sum=0
for n in $(seq 2 2 100)
do
((sum+=n))
done
echo $sum
运行结果:
2550
seq 是一个 Linux 命令,用来产生某个范围内的整数,而且能够设置步长,不了解的读者请自行百度。seq 2 2 100表示从 2 开始,每次增长 2,到 100 结束。
再如,列出当前目录下的全部 Shell 脚本文件:
#!/bin/bash
for filename in $(ls *.sh)
do
echo $filename
done
运行结果:
demo.sh
test.sh
abc.sh
ls 是一个 Linux 命令,用来列出当前目录下的全部文件,*.sh表示匹配后缀为.sh的文件,也就是 Shell 脚本文件。
4) 使用 Shell 通配符
Shell 通配符能够认为是一种精简化的正则表达式,一般用来匹配目录或者文件,而不是文本,不了解的读者请猛击《Linux Shell 通配符(glob 模式)》。
有了 Shell 通配符,不使用 ls 命令也能显示当前目录下的全部脚本文件,请看下面的代码:
#!/bin/bash
for filename in *.sh
do
echo $filename
done
运行结果:demo.shtest.shabc.sh