Shell里的for循环语句写法。我们分别用命令行和shell脚本来进行演示。
常见的一种for结构如下。for里面要跟着do
和done
关键字。
1 2 3 4
| for i in {1..3} do echo YES $i # 这里是循环体 done
|
数字范围
数字范围,例如从1到3,从1到100。
for in
for in 的写法,定义i
为变量,使用大括号来指定范围。范围的数字之间有2个点..
。例如{1..3}
1 2 3 4
| $ for i in {1..3};do echo now is $i; done now is 1 now is 2 now is 3
|
上面是命令行,一行把所有的指令写完。也可以再加一行代码,同样用分号;
来分隔。
1 2 3 4 5 6 7
| $ for i in {1..3};do echo now is $i;echo rustfisher.com; done now is 1 rustfisher.com now is 2 rustfisher.com now is 3 rustfisher.com
|
或者写成脚本。其实就是拆成几行。
1 2 3 4 5 6 7
| #!/bin/bash
for i in {1..3} do echo now is $i echo rustfisher.com done
|
前面我们用的是大括号来指定循环范围。我们也可以用$(seq 1 3)
。
开头依旧是for i in
1 2 3 4 5 6 7
| $ for i in $(seq 1 3);do echo now is $i;echo rustfisher.com; done now is 1 rustfisher.com now is 2 rustfisher.com now is 3 rustfisher.com
|
写成脚本如下
1 2 3 4 5 6 7
| #!/bin/bash
for i in $(seq 1 3) do echo now is $i echo rustfisher.com done
|
实际上我们使用了seq
命令。seq后面接2个数字,可以输出这个范围内的数字。
1 2 3 4 5 6 7 8 9 10 11 12
| $ seq 1 5 1 2 3 4 5 ~ $ seq 5 1 5 4 3 2 1
|
for((i=1;i<=3;i++))
我们也可以写成像Java/C语言里的for循环那样。但要注意这里的for有2层小括号。
1 2 3 4
| $ for((i=1;i<=3;i++));do echo -n now is [$i] ;echo rustfisher.com; done now is [1]rustfisher.com now is [2]rustfisher.com now is [3]rustfisher.com
|
更改一下步进值,改为i+=2
1 2 3
| for((i=1;i<=3;i+=2));do echo -n now is [$i] ;echo rustfisher.com; done now is [1]rustfisher.com now is [3]rustfisher.com
|
或者加上一些小运算,用expr
加上我们想要的运算。注意$i
与\*
和3
之间要有空格。
1 2 3
| $ for((i=1;i<=3;i+=2));do echo -n $(expr $i \* 3) ' ' ;echo rustfisher.com; done 3 rustfisher.com 9 rustfisher.com
|
后面加的空格是为了隔开好看一些。在shell脚本中,我们有时候会定义变量。变量也可以作为for循环的范围。
1 2 3 4 5 6 7 8 9
| #!/bin/bash
startNum=1 endNum=3
for i in $(seq $startNum $endNum) do echo current is $i done
|
我们定义2个变量startNum
与endNum
。要使用它们的值时,需要加上$
符号。字符循环
for循环可以与一些指令结合起来,获取指令中的结果。
for i in ls
先用命令行看一个效果,for与ls结合使用
1 2
| $ for i in `ls`; do echo $i ; done for1.sh
|
当前目录里只有1个文件。如果是ls -a
命令,输出会更多。
1 2 3 4
| $ for i in `ls -a`; do echo $i ; done . .. for1.sh
|
换一个目录,我们可以输出所有png文件的文件名
1 2 3 4 5 6 7 8 9
| $ for i in `ls *.png`; do echo $i ; done android-cover-2.png fish.png ic_book_blue.png ic_tools_gear.png ic_web.png kotlin-android-1.png python-logo.png ts-blue-1.png
|
for i in ll
换成ll
命令,输出更加丰富
1 2 3 4 5 6 7 8 9 10 11 12
| $ for i in `ll`; do echo $i ; done total 8 -rw-r--r-- 1 rustfisher staff 183 6 19 21:25 for1.sh
|
我们知道ll
命令会输出当前目录下的文件信息
1 2 3
| $ ll total 8 -rw-r--r-- 1 rustfisher staff 183 6 19 21:25 for1.sh
|
结合for循环可以看出,for循环是获取了空格或换行为间隔的字符串。
显示各个子目录里md文件的个数
1
| for i in `ls`; do echo $i; find $i -name "*.md" | wc -l; done
|
字符串变量
那么我们可以在脚本中尝试一些,for循环配合字符串
1 2 3 4 5 6 7
| #!/bin/bash
word="Welcome to rustfisher.com" for i in $word do echo $i done
|
word
中间有很多个空格,但输出的依旧是这3行。
1 2 3
| Welcome to rustfisher.com
|
进一步扩展,定义3个变量,都作为for in的参数
1 2 3 4 5 6 7 8 9
| #!/bin/bash
word1="Welcome to rustfisher.com" word2="Hello world" word3="我很好" for i in $word1 $word2 $word3 do echo $i done
|
输出
1 2 3 4 5 6
| Welcome to rustfisher.com Hello world 我很好
|
目录
例如查找某个目录下的文件。
当前目录中有一个img目录,里面有一些图片。我们在for in 后面用img/*
来表示查找这个目录中所有文件。
1 2 3
| $ for i in img/*; do echo $i ; done img/android-2botsm.jpg img/android-cover-2.png
|
如果只想看png文件,路径写为img/*.png
。
1 2
| $ for i in img/*.png; do echo $i ; done img/android-cover-2.png
|
从上面的例子可以看出,for in结构用的十分频繁。