[PowerShell入门]选择结构和循环结构
2017-06-06 17:02
239 查看
PowerShell入门
学习完PowerShell中的关系运算和逻辑运算,就可以开始学习PowerShell的控制结构了。尽管本篇尽量减少了对于学习过其他语言读者来说不重要的内容,但为了照顾初学者(或许真的有吧…),所以还是保留了一些有必要详细讲解的内容。关于PowerShell的选择结构和循环结构中需要注意的东西,文章都相应地做了着重标记,所以非初学者的读者们可以跳过那些基础内容,直接阅读着重内容即可。
下文中关于各种语句的基本结构,在此约定:圆括号()代表表达式应该用圆括号包含。花括号{}代表这是一个代码块。方括号[]代表这是一个可选项。竖线|代表“或”。双点..代表该结构可以重复出现。前缀加上$的代表这是一个变量。
选择结构
if
PowerShell中if语句用于根据判定给定条件的结果来控制程序接下来的动作,其基本结构为if (condition) {statement} [elseif (condition) {statement} ..] [else {statement}]。
程序从if子句开始从上至下逐个判断condition的结果是否为$true,是的话就执行后面的代码块并退出结构。如果没有任何子句的condition返回$true,则执行else子句后面的代码块。
# 下面的程序会根据$p变量不同的值而打印不同的字符串 $p = "bj" if ($p -eq "bj") { "Welcome to BeiJing!" } elseif ($p -eq "cq") { "Welcome to ChongQing!" } else { "Welcome to China!" }
唯一需要注意的地方是PowerShell中的elseif是一个完整的关键字,而不是else和if的组合,中间是没有空格隔开的。
switch
如果选择结构有多个分支,使用if语句写起来就非常繁琐。选择分支越多,elseif子句就越多,程序就会越来越冗长,影响可读性。而switch语句就是用于简化多分支选择结构的。switch语句的结构比较复杂,如下:
switch [-regex|-wildcard|-exact] [-casesensitive] (item)|-file filename { {condition} {statement} .. [default {statement}] }
switch关键字后面可以加上可选的参数:
-regex代表接受正则表达式对字符串进行匹配。
-wildcard代表接受通配符对字符串进行匹配。支持?、*、[a-z]等形式的通配符。
-exact代表精确匹配,使用精确匹配的话switch语句就不会识别字符串中的通配符和正则表达式。
-casesensitive代表大小写敏感,加上该参数的时候switch默认使用-ceq而不是-ieq。
以上的参数可以使用任意长度的缩写代替,比如-casesensitive可以写为-case,也可以写为-c。
item代表传入switch语句进行判断的变量或者字面量,如果使用了-file参数,则switch读取后面提供的文件中的内容进行匹配。
condition代表需要比较的条件,它可以是一个字面量或者用花括号包含起来的条件/逻辑表达式,当它是一个字面量时switch语句会使用-eq/-like/-match操作符将它与item进行比较。当condition返回$true时执行后面的代码块,否则判断下一个条件是否符合。如果没有任何条件符合,则执行default后面的代码块。在执行完statement后,PowerShell会继续执行下面的语句,如果想在执行之后跳出结构,那么需要在statement的最后加上break语句跳出整个switch。
switch语句也支持传入一个集合,这时候的switch其实相当于foreach和if的结合。在代码块中可以用$_代表当前变量。
# 判断1到10中哪些数字是偶数,哪些是奇数 $nums = 1..10 switch ($nums) { {($_ % 2) -eq 0} {"$_ 是偶数"} {($_ % 2) -ne 0} {"$_ 是奇数"} }
循环结构
while
while语句用于根据特定条件运行循环,其基本结构为while (condition) {statement}。
程序进入while语句后,先判断condition是否为$true,是的话则执行代码块,然后再次判断condition的值。否则退出循环。
# 下面的程序从5开始打印字符串直到$x不大于1 $x = 5 while ($x -gt 1) { "$x is greater than 1" $x-- }
do..while..和do..until..
与while语句不同,do..while和do..until..先执行一次循环体,再判断循环条件是否成立。它们的基本结构为do {statement} while|until (condition)。它们的区别是do..while..在条件成立的时候继续循环,而do..until..在条件成立的时候退出循环。
在实际的应用中,如果想保证循环体至少执行一次,那么可以选择do..while..或者do..until..结构。
# 循环读入一个字符串并将其原样输出,直到输入的字符串为"exit" do { $n = Read-Host Write-Output $n } until ($n -eq "exit")
foreach
foreach用于集合的遍历,其基本结构为foreach ($item in collection) {statement}。其中collection是要进行遍历的集合,可以是变量或者字面量,item是用于代表集合中元素的临时变量。
# 遍历city集合并打印字符串 $city = "ChongQing", "BeiJing", "XiAn" foreach ($c in $city) { "Welcome to $c" }
PowerShell中的ForEach-Object和ForEach()方法
其实PowerShell中还有另外两种遍历集合的方法,一种是使用ForEach-Object命令,还有一种是直接使用集合对象的ForEach()方法。上面的代码也可以用ForEach-Object改写为
"ChongQing", "BeiJing", "XiAn" | ForEach-Object {"Welcome to $_"}。或者用ForEach()方法改写为
("ChongQing", "BeiJing", "XiAn").ForEach({"Welcome to $_"})。
这两种“foreach”跟真正的foreach语句是不一样的。foreach语句不使用管道,当我们使用foreach语句来进行集合遍历的时候,实际上集合会先被加载到内存当中,再进行遍历。而ForEach-Object使用管道,每次只处理一个对象,内存的消耗比foreach语句小。但由于不是真正的循环结构,在ForEach-Object和ForEach()方法中的continue语句和break语句都无法正常工作。
另外,ForEach-Object也可以写为foreach,但这个“foreach”跟foreach语句不同,它只是ForEach-Object的alias,它只有在管道操作符右边的时候才会起作用。
> Get-Alias foreach CommandType Name Version Source ----------- ---- ------- - Alias foreach -> ForEach-Object
for
for语句用于固定数量的循环,其基本结构为for (init; condition; increment) {statement}。其中init用于初始化循环所需要用的变量,init只会执行一次,condition用于判断是否继续执行循环,increment用于在每次循环结束后递增或递减循环用到的变量。其中,init和increment可以为空。
# 打印0到9 for ($i = 0; $i -lt 10; $i++) { "$i" }
关于使用for代替while
有些书本或者教程讲循环结构的时候总会提到:for语句可以完全代替while语句,只需要把init和increment留空,for语句的作用也就完全跟while语句一样了。这种说法虽然在语法层面上没有错,但对于新手来说却是一种误导。博主认为,for和while所表达的“语义”是完全不同的。for一般用于固定次数的循环,或者在某些语言里面充当foreach的角色,而while则用于未知次数的循环或者无限循环当中,这两者是完全不该混用的。混用for和while会使程序的可读性变差,所以在条件允许的情况下,应当尽量分清几种循环结构的语义和使用场景。continue和break
当我们在使用循环结构的时候,在特定条件下可能要跳过某次循环或者退出整个循环结构。此时可以使用continue语句和break语句。continue语句的作用是跳过当前循环进入下一次循环,break语句则跳出整个循环结构。PowerShell中的循环结构都可以使用continue语句和break语句。# 循环遍历1到10的数组,当$i等于5的时候跳过当前循环,直接执行下一次循环 foreach ($i in 1..10) { if ($i -eq 5) { continue } "$i" }
总结
PowerShell提供了多种选择结构和循环结构用于控制程序的运行,熟练掌握这些结构是构建复杂程序的基础。对于学习过其他语言的人来说,这些内容应该都不难理解。而对于学习PowerShell的人来说,学习过其他语言的应该占多数,所以本篇博客也尽量减少了那些无关紧要的废话,对其中一些与其他语言有区别的点相应地作了标记。每次写博客,博主都尽量找了更多更详细的资料,以求能把一些没人注意到的细节讲清楚(比如这篇博客中关于switch中的-file参数,pstips的在线教程中就没提到,是在一个外文网站ss64中翻到的),希望这些细节对读者们能有所帮助。我的其他PowerShell入门相关文章:
[PowerShell入门]变量、赋值、算术运算、类型转换、数组、注释
[PowerShell入门]关系运算和逻辑运算
参考资料:
pstips
ss64
Powershell 中的 foreach 和 foreach-object
感谢以上内容提供者!
相关文章推荐
- 学习Unity3D第五天之脚本入门(选择结构和循环结构)。
- Unity3D学习之脚本入门(选择结构和循环结构)
- JAVA菜鸟入门篇 - 控制语句:顺序结构、选择结构和循环结构(五)
- 黑马程序员——选择结构if、switch,循环结构while、do-while、for
- 循环控制结构程序05 - 零基础入门学习C语言20
- 达内-----选择循环结构与数组
- ASP入门教程-多分支条件选择结构
- .NET入门(九)测试各种循环结构,for,while和do while
- 视频13--学习心得--循环的嵌套(循环与循环,循环与选择结构)
- 循环控制结构程序04 - 零基础入门学习C语言19
- 循环控制结构程序04 - 零基础入门学习C语言19
- 循环控制结构程序06 - 零基础入门学习C语言21
- Visual Studio 2005入门 之 控制结构一(循环)[视频]
- 循环控制结构程序07 - 零基础入门学习C语言22
- Objective-C 2.0 学习笔记四(循环结构和选择结构)
- 循环控制结构程序05 - 零基础入门学习C语言20
- 循环结构、选择结构练习
- Lua中的选择、循环结构
- 循环控制结构程序01 - 零基础入门学习C语言16
- 循环控制结构程序07 - 零基础入门学习C语言22