for命令格式:
– list参数:迭代中要用的一系列值
– 每个迭代中,变量var会包含列表中的当前值
– do和done语句之间输入的命令可以是一条或多条标准的bash shell命令
1
2
3
4
forvarinlist
do
commands
done
读取列表中的值
for命令最基本的用法就是遍历for命令自身中定义的一系列值:
在最后一次迭代后,$test变量的值会在shell脚本的剩余部分一直保持有效,除非修改它
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$cattest
#!/bin/bash
fortestinAlabama Alaska Arizona Arkansas California Colorado
do
echoThe next state is$test
done
echo"The last state we visited was $test"
test=Connecticut
echo"Wait , now we're visiting was $test"
$./test
The next state isAlabama
The next state isAlaska
...
The last state we visited was Colorado
wait,now we're visiting Connecticut
读取列表中的复杂值
对于单双引号问题的解决
使用转义字符来将单引号转义
使用双引号来定义用到单引号的值
1
2
3
4
5
6
7
8
9
10
11
$cattest
#!/bin/bash
fortestinIdon't know if "this'll"work
do
echo"word:$test"
done
$./test
word:I
word:don't
...
对于空格的问题解决:for循环假定每个值都是用空格分割的
解决方法:用双引号来将这些值圈起来,如”New York”
从变量读取列表
将一些列的值都集中存储在了一个变量中,然后遍历整个列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$cattest
#!/bin/bash
list=“Alabama Alaska Arizona Arkansas California Colorado”
list=$list" Connecticut"
forstate in$list
do
echo"Have you ever visited $state?"
done
$./test
Have you ever visited Alabama?
...
Have you ever visited Connecticut?
$
从命令读取值
生成列表中要用的值的另外一个途径就是使用命令的输出
可以使用反引号来执行任何能产生输出的命令,然后在for命令中使用该命令的输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$cattest
#!/bin/bash
file="states"
forstate in`cat$file`
do
echo"Visit beautiful $state"
done
$catstates
Alabama
Alaska
...
$./test
Visit beautiful Alabama
Visit beautiful Alaska
...
更改字段分隔符
默认情况下,bash shell会将下列字段当做字段分隔符
空格
制表符
换行符
可以在shell脚本中临时更改IFS环境变量的值来限制一下被bash shell当作字段分隔符的字符
例如
修改IFS值使其只能识别换行符:IFS=$’\n’
遍历一个文件中以冒号分隔的值:IFS=:
如果指定多个IFS字符,只要将它们在赋值行串起来就行:IFS=$’\n:;’” (将换行符、冒号、分号和双引号作为字段分隔符)
常用的做法:在改变IFS值之前保存原来的IFS值,之后再回复它
1
2
3
4
IFS.OLD=$IFS
IFS=$'\n'
IFS=$IFS.OLD
用通配符读取目录
for命令可以来自动变里满是文件的目录,操作时,必须在文件名或路径名中使用通配符,它会强制shell使用文件扩展匹配
文件扩张匹配:生成匹配指定的通配符的文件或路径名的过程
1
2
3
4
5
6
7
8
9
10
11
12
13
...
forfilein/home/rich/test/*
do
if[-d"$file"]
then
echo"$file is a directory"
elif[-f第12章:更多结构化命令
第6章:理解Linux文件权限.md"$file"]
then
echo"$file is a file"
fi
done
...
Linux中,目录名和文件名中包含空格是合法的,要容纳这种值,应该将$file变量用双括号圈起来
可以在for命令中通过列出一系列的目录通配符来将目录查找的方法和列表方法结合起来
1
2
3
4
5
6
7
8
9
10
11
12
13
...
forfilein/home/rich/.b*/home/rich/badtest
do
if[-d"$file"]
then
echo"$file is a directory"
elif[-f"$file"]
then
echo"$file is a file"
else
echo"$file doesn't exist"
fi
done
C语言的for命令
bash中C语言风格的for循环的基本格式:for (( variable assignment : condition : iteration process ))
例如:for (( a = 1; a < 10; a++ ))
一些没有遵循标准的bash shell for命令
给变量赋值可以有空格
条件中的变量不以美元符开头
迭代过程的算式未用expr命令格式
1
2
3
4
5
6
7
8
9
10
11
$cattest
#!/bin/bash
for((i=0;i<10;i++))
do
echo"The next number is $i"
done
$./test
The next number is1
The next number is2
...
使用多个变量
C语言风格的for命令允许为迭代使用多个变量
循环会独立处理每个变量,允许为每个变量定义不同的迭代过程
当有多个变量时,只能在for循环中定义一个条件
1
2
3
4
5
6
...
for((a=1,b=10;a<=10;a++,b--))
do
echo"$a - $b"
done
...
while命令的基本格式
格式如下:
while命令中定义的test命令和if-then中定义是一样的格式
while命令的关键:指定的test命令的退出状态码必须随着循环中运行的命令改变,否则while会不停循环下去
最常用的test命令用法是,用方括号来查看命令中用到的shell变量的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
whiletestcommand
do
other commands
done
//eg:
...
var1=10
while[$var1-gt0]
do
echo$var1
var1=$[$var1-1]
done
...
使用多个测试命令
while命令中允许在while语句行定义多个测试命令,只有最后一个测试命令的退出状态码会被用来决定什么时候结束循环
until命令
until命令和while命令工作方式完全相反
until命令要求制定一个通常输出非零退出状态码的测试命令
只有测试命令的退出状态码非零,bash shell才会指定循环中列出的那些命令
一旦测试命令返回了退出状态码0,循环就结束了
1
2
3
4
untiltestcommands
do
other commands
done
与while命令类似,可以在until命令语句中有多个测试命令,最后一个命令的退出状态码决定bash shell是否执行定义好的其他命令
嵌套循环
脚本允许使用嵌套循环
循环处理文件数据
通常,必须遍历存储在文件中的数据,这需要结合两种技术
使用嵌套循环
修改IFS环境变量
使用环境变量IFS,强制for命令将文件中的每行都当成单独一个条目,即便数据中有空格也是如此
一旦从文件中提取除了单独的行,可能需要再次循环来提取其中的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$cattest
#!/bin/bash
IFS.OLD=$IFS
IFS=$'\n'
forentry in`cat/etc/passwd`
do
echo"values in $entry -"
IFS=:
forvalue in$entry
do
echo" $value"
done
done
$./test
Value inrich:x:501:501:Rich Blum:/home/rich:/bin/bash-
rich
x
501
...
/bin/bash
Value in...
控制循环
break命令
break命令:退出任意类型的循环,包括while和until循环
指定跳出外部循环:break n
n:指定要跳出的循环层级
默认情况下,n为1,表明跳出的是当前的循环
若为2:break命令就会停止下一级的外部循环
continue命令
提早结束执行循环内部的命令但不完全终止整个循环的一个途径
continue命令允许使用参数来指定要继续哪级循环:continue n
n:要继续的循环层级
处理循环的输出
在shell脚本中,要么关节要么重定向循环的输出
可以在done命令后面添加一个处理命令:
shell会将结果重定向到文件output.txt中,而不是显示在屏幕上
1
2
3
4
5
6
7
8
9
forfilein/home/rich*
do
if[-d"$file"]
then
echo"$file is a directory"
elif
echo"$file is a file"
fi
done>output.txt
这种方法同样适用于将循环的结果管接给另一个命令
以下例子说明将输出的结果通过sort命令重新排序输出
Shell
1
2
3
4
5
6
...
for...
...
done|sort
echo"This completes our place to go"
$