for 循环两种风格:

 c 语言风格

 for in 风格

 

Shell for循环和for int循环详解

 

c 语言风格 :

这种风格只适用与/bin/bash, /bin/sh不支持这种风格 。

for((exp1; exp2; exp3))
do
    statements
done

几点说明:

  • exp1、exp2、exp3 是三个表达式,其中 exp2 是判断条件,for 循环根据 exp2 的结果来决定是否继续下一次循环;
  • statements 是循环体语句,可以有一条,也可以有多条;
  • do 和 done 是 Shell 中的关键字。

它的运行过程为:
1) 先执行 exp1。
2) 再执行 exp2,如果它的判断结果是成立的,则执行循环体中的语句,否则结束整个 for 循环。
3) 执行完循环体后再执行 exp3。
4) 重复执行步骤 2) 和 3),直到 exp2 的判断结果不成立,就结束循环。

上面的步骤中,2) 和 3) 合并在一起算作一次循环,会重复执行,for 语句的主要作用就是不断执行步骤 2) 和 3)。
exp1 仅在第一次循环时执行,以后都不会再执行,可以认为这是一个初始化语句。exp2 一般是一个关系表达式,决定了是否还要继续下次循环,称为“循环条件”。exp3 很多情况下是一个带有自增或自减运算的表达式,以使循环条件逐渐变得“不成立”。

举例如下:

#!/bin/bash # 这里是能是bin/bash bin/sh是不支持c语言风格的

sum=0

for ((i=1; i<=100; i++))  # 这里是双括号
do
    ((sum += i))
done

echo "The sum is: $sum"

for in 风格:

这种风格/bin/bash和bin/sh都适用

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 中的所有值,循环就结束了。

#!/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) 直接给出具体的值

#!/bin/bash

for str in "C语言中文网" "http://c.biancheng.net/" "成立7年了" "日IP数万"
do
echo $str
done

运行结果:
C语言中文网
http://c.biancheng.net/ 成立7年了
日IP数万

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)  # 从2到100,包括100,步长是2
do
((sum+=n))
done

echo $sum

运行结果:
2550


再如,列出当前目录下的所有 Shell 脚本文件:

#!/system/bin/sh
function ergodic(){
	for file in `ls $1`
	do
		if [ -L $1"/"$file ] #排除link文件
		then
			echo >> /data/Thermal.txt #生成空格
			echo "this is a Link: "$1"/"$file >> /data/Thermal.txt
			continue
		elif [ $file = "autosuspend_delay_ms" ] #排除不能读的文件
		then
			echo >> /data/Thermal.txt
			echo "cann't read: "$1"/"$file >> /data/Thermal.txt
			continue
		elif [ -d $1"/"$file ] #如果是文件夹接着递归
		then
			ergodic $1"/"$file
		else #读内容
			echo >> /data/Thermal.txt
			echo $1"/"$file >> /data/Thermal.txt
			cat $1"/"$file >> /data/Thermal.txt
		fi
	done
}

function generateFile(){
	echo "----------Thermal Information Start----------" > /data/Thermal.txt
}
INIT_PATH="/sys/devices/virtual/thermal"
generateFile
ergodic $INIT_PATH

ls 是一个 Linux 命令,用来列出当前目录下的所有文件,*.sh表示匹配后缀为.sh的文件,也就是 Shell 脚本文件。

4) 使用 Shell 通配符

Shell 通配符可以认为是一种精简化的正则表达式,通常用来匹配目录或者文件,而不是文本,不了解的读者请猛击《Linux Shell 通配符(glob 模式)》。

#!/bin/bash

for filename in *.sh
do
echo $filename
done

运行结果:
demo.sh
test.sh
abc.sh

5) 使用特殊变量

Shell 中有多个特殊的变量,例如 $#、$*、$@、$?、$$ 等(不了解的读者请猛击《Shell特殊变量》),在 value_list 中就可以使用它们。

#!/bin/bash

function func(){
for str in $@
do
echo $str
done
}

func C++ Java Python C#

运行结果:
C++
Java
Python
C#

其实,我们也可以省略 value_list,省略后的效果和使用$@一样。请看下面的演示:

#!/bin/bash

function func(){
for str
do
echo $str
done
}

func C++ Java Python C#

运行结果:
C++
Java
Python
C#