SHELL脚本的基础知识3——更多结构化命令
for,while,until
1、for命令
for var in list
do
commands
done
在参数list中提供一系列用于迭代的值。
(1)读取列表中的值
var取本次循环中的list中的值。而且出了循环后,变量var还保留最后一次循环的值,可以继续使用。
(2)读取列表中的复杂值
问题1:
当列表值当中有单引号,就会试图用它们来定义一个单独的数据值
有两种方法解决这个问题:
使用转义字符(反斜杠符号)来转义单引号
使用双引号来定义使用单引号的值
问题2:
运行多字值
即如果有包含空格的数据值,就必须使用双引号将它们包围起来。
(3)从变量读取列表
可以使用变量包含用于迭代的标准的文本值列表,并且还可以使用赋值语句向包含在变量中的已存在列表添加一条项目
(4)读取命令中的值
可以使用反引号字符来执行生成输出的任何命令,然后在for命令中使用命令的输出。
(5)改变字段分隔符
环境变量IFS定义了bash shell用作字段分隔符的字符列表,默认情况下,bash shell将空格、制表符、换行符看作字段分隔符。
所以,当处理需要包含空格的数据时,就会被处理成多个数据字段,要解决该问题,就可以在shell脚本中暂时更改环境变量IFS的值,限制bash shell看作是字段分隔符的字符。
例如,将IFS的值改为只识别换行符:IFS=$’\n’,这样就可以在每一个数据字段中包含空格和制表符了。
想指定多个IFS字符,只需要将它们在赋值行中串联起来即可。
ex: 使用换行符,冒号,分号和双引号字符作为字段分隔符:IFS=$’\n’:;”
(6)使用通配符读取目录
1)可以使用for命令自动迭代文件的目录,就是迫使shell使用文件通配,即生成与指定通配符匹配的文件或路径名的过程。
当不知道目录中的所有文件名时,使用该功能
2)通过在for命令中列出一系列目录通配符,可以在同一个for语句中将目录搜索方法和列表方法结合起来。
for语句首先使用文件通配符生成的文件列表,然后迭代列表中的下一个文件,可以结合列表中任意数目的通配符进行迭代。
注意:一般在试图处理某文件或目录前,检测一下是否存在是个好习惯
2、C式的for命令
(1)C语言中的for命令
基本格式:for(( variable assignment ; condition ; iteration process ))
注意,有几项不遵循标准bash shell的for方法:
1)变量的赋值可以包含空格
2)条件中的变量不以美元符号做前缀
3)迭代处理式不使用expr命令格式
(2)使用多个变量
C式的for命令也允许使用多个变量迭代,但只可以在for循环中定义一个条件。
3、while命令
(1)基本格式
while the command
do
other commands
done
最常见的是使用test命令括号来检验用于循环命令的shell变量的值
(2)使用多条测试命令
bash shell中允许在while语句行定义多条test命令。但是实际上却只有最后一条测试命令的退出状态是用来决定循环是何时停止的。
在多命令的while语句中,所有的测试命令在每次迭代中都执行,包含测试命令失败的最后一次迭代。
4、until命令
(1)until命令刚好与while命令相反,需要制定一条测试命令,通常产生一个非0的退出状态。只要测试命令的退出状态非0,就继续执行内部循环,一旦测试命令返回0,则循环停止。
(2)基本格式:
until the commands
do
other commands
done
(3)与while相同,也可以在until命令语句中使用多条测试命令。只有最后一条命令的退出状态能够决定bash shell是否执行其他定义的命令。
5、嵌套循环
一条循环语句可以在循环中使用任何类型的命令,包括其他循环命令。
需要注意的:因为是在一个迭代内部执行另一个迭代,所以它增加了正在运行的命令的运行次数。
混合循环同样使用。
6、文件数据的循环
当需要迭代存储在文件内部的项,就需要结合使用嵌套循环,并更改环境变量IFS
通过改变IFS使得for命令将文件中的一行作为单独的一项进行处理。
而提取了一行后,又需要对这一行内的个别数据进行处理,则需要再次设置IFS,并进行内部嵌套循环。
这是处理文本中用分隔符分隔数据的一种好办法,也是导入电子表数据的一种常用方法
7、控制循环
(1)break命令
可以使用break跳出任何类型的循环。有以下几种使用方式
1)跳出单循环:当只有一层循环时,直接终止
2)跳出内循环:当有嵌套循环时,终止所在的最里面的内部循环
3)跳出外循环:可能有时处于内循环,却需要跳出外循环。可以使用break命令带上参数值:
break n (n表示要跳出的循环级别,默认情况下是1,也就是从当前层向外计数)
(2)continue命令
1)停止本次循环,跳过continue之后的语句,马上开始下一次循环。
注意:若是增加测试条件变量的语句在被跳过的代码中,就会出错。
2)continue命令也可以使用参数,指定要继续的循环级别
continue n
(n表示要跳出的循环级别,默认情况下是1,也就是从当前层向外计数)
8、处理循环的输出
可以在shell脚本中使用管道或者重定向循环输出结果
通过在done命令末尾添加处理命令来做到这一点,
ex1: done > output.txt(重定向输出)
(在done之前产生的输出就不再打印在终端中,而全部写入output.txt)。
ex2: done | sort(管道输出)
(在done之前产生的输出顺序将被排序后,再输出)。