代码改变世界

PowerShell 学习(二):流程控制语句

2010-04-28 21:08  囧月  阅读(...)  评论(...编辑  收藏

PowerShell的流程控制语句有:

  1. 分支
    1. if
    2. switch
  2. 循环
    1. for
    2. foreach
    3. while
  3. 跳转
    1. break
    2. continue

 

1.1 if

  语法
    以下示例说明 If 语句的语法:

        if (<test1>)
            {<statement list 1>}
        [elseif (<test2>)
            {<statement list 2>}]
        [else
            {<statement list 3>}]

示例:
        if ($a -gt 2)
        {
            Write-Host "The value $a is greater than 2."
	}
        elseif ($a -eq 2)
        {
            Write-Host "The value $a is equal to 2."
        }
        elseif ($a -eq 3)
        {
            Write-Host "The value $a is equal to 3."
        }
	else
        {
            Write-Host "The value $a is less than 2 or was not created or initialized."
        }
 
1.2 switch
    如果要通过 switch 获取的值是一个数组,那么将从元素 0 开始按顺序计算该数组中的每个元素。至少必
    须存在满足至少一个条件的元素,否则将发生错误。如果存在多个默认子句,将发生错误。

    完整的 switch 语法如下:

        switch [-regex|-wildcard|-exact][-casesensitive] ( pipeline )
    或

        switch [-regex|-wildcard|-exact][-casesensitive] -file filename

    后跟

        { 
            "string"|number|variable|{ expression } { statementlist } 
            default { statementlist }
        }

    默认情况下,如果未使用任何参数,那么 Switch 按采用"不区分大小写的精确匹配"进行操作。如果
    "pipeline"的结果为数组,那么将从 0(零)开始按偏移升序依次对数组中的每个元素进行计算。

    Switch 代码块中必须至少存在一个条件元素,并且只能存在一个 default 子句。如果存在多个 
    default 子句,将引发 ParseException 异常。

    Switch 具有以下参数:

        Regex	        指示如果匹配子句为字符串,则将其视为正则表达式字符串。使用
        		此参数将禁用 Wildcard 和 Exact。如果匹配子句不是字符串,将忽略此参数。

        Wildcard	指示如果匹配子句为字符串,则将其视为通配符字符串。使用此参数将禁用 Regex 和 
        		Exact。如果匹配子句不是字符串,将忽略此参数。

        Exact	        指示如果匹配子句为字符串,则必须精确匹配。使用此参数将禁用 Wildcard 和 Regex。
			如果匹配子句不是字符串,将忽略此参数。

        CaseSensitive	如果匹配子句为字符串,则将它修改为区分大小写。如果匹配子句不是字符串,将忽略此参数。

        File	        从文件(或样本)而不是从语句获取输入。如果使用了多个 File 参数,
			则使用最后一个参数。读取文件中的每一行,并对其执行 switch 块。

    允许多次使用 Regex、Wildcard 或 Exact。但是,只有使用的最后一个参数控制 Switch 的行为。
一条 switch 语句实际上等效于一系列 If 语句。它将表达式与每个条件逐一进行匹配。如果找到匹配
项,即执行与该条件相关联的操作。基本的 switch 语句形式如下(很奇怪的看到不需要break):
        PS> $a = 3
        PS> switch ($a) {
            1 {"It is one."}
            2 {"It is two."}
            3 {"It is three."}
            4 {"It is four."}
            }
        
        It is three.
这一简单的示例获取一个值,并将该值与列表中的每个条件进行比较。执行的操作是根据匹配情况
回显一个字符串。但是,如果每个条件都检查,可能会遇到问题。例如(这个更奇怪,居然可以有相同的expression):

        PS> $day = "day5"
        PS> switch ($day){
            day1 {"Monday"; break}
            day2 {"Tuesday"; break}
            day3 {"Wednesday"; break}
            day4 {"Thursday"; break}
            day5 {"Friday"; break}
            day6 {"Saturday"; break}
            day7 {"Sunday"; break}
            day5 {"Too many days"; break}
            }
        
        Friday

可以使用CaseSensitive区分大小写:
        PS> $day = "Day5"
        PS> switch -CaseSensitive ($day){
            day1 {"Monday"}
            day2 {"Tuesday"}
            day3 {"Wednesday"}
            day4 {"Thursday"}
            Day5 {"Friday"}
            day6 {"Saturday"}
            day7 {"Sunday"}
            day5 {"Too many days"}
            }
        Friday
正则表达式匹配:
        PS> $day = "day5"
        PS> switch -regex ($day){
            ^[a-z]+$ {"字母,匹配为:" + $_; break}
            ^[\d]+$ {"数字,匹配为:" + $_; break}
            ^\w+$ {"字母+数字,匹配为:" + $_; break}
            }
        
        字母+数字,匹配为:day5
正则表达式匹配多个:
$day = "day5","day6"
switch -regex ($day){
    ^[a-z]+$ {"字母,匹配为:" + $_; }
    ^[\d]+$ {"数字,匹配为:" + $_; }
    ^\w+$ {"字母+数字,匹配为:" + $_; }
    } 

字母+数字,匹配为:day5

字母+数字,匹配为:day6

通配符(*)匹配:

    $day = "day5"
    switch -Wildcard ($day){
        day2 {"day2,匹配为:" + $_; }
        day3 {"day3,匹配为:" + $_; }
        day* {"通配符,匹配为:" + $_; }
    }
    通配符,匹配为:day5

2.1 for

  语法
      下面显示了 For 语句的语法。
      
  
          for (<init>; <condition>; <repeat>)
          {<statement list>}
 示例:
       for($i=1; $i -le 10; $i++){Write-Host $i}

  没有什么特别的地方

 

 

2.2 foreach

  语法        
      下面显示了 Foreach 语法:

        
          foreach ($<item> in $<collection>){<statement list>}

示例:

          $letterArray = "a","b","c","d"
          foreach ($letter in $letterArray)
          {
              Write-Host $letter
          }
 
  命令管道之内的 Foreach 语句 
      当 Foreach 出现在命令管道中时,Windows PowerShell 将使用 foreach 别名调用 ForEach-Object 命令。
      在命令管道中使用 foreach 别名时,无需像在 Foreach 语句中那样包含 ($<item> in $<collection>) 语法。
      这是因为管道中的前一命令已提供此信息。在命令管道中使用的 foreach 别名的语法如下:
        

          <command> | foreach {<command_block>}
  示例:
	"a","b","c","d" | foreach {
		write-host $_
	}
 
  foreach 别名还支持起始命令块、中间命令块和结尾命令块。起始命令块和结尾命令块只运行一
      次,而中间命令块在每次 Foreach 循环访问一次集合或数组时都运行一次。
        

      Foreach 别名在具有起始、中间和结尾命令块组的命令管道中使用时的语法为:
        

          <command> | foreach {<beginning command_block>}{<middle 
          command_block>}{<ending command_block>}

 
      以下示例演示了起始、中间和结尾命令块的用法。

    "a","aa","b","bb","c" | foreach {
        $x=$y=0} {
        if ($_.length -eq 1) { $x++ } else { $y++ }
        } {
        write-host "$x --- $y" }
 
2.3 while
    下面说明 While 语句的语法:

        while (<condition>){<statement list>}

   示例:
        while($val -ne 3)
        {
            Write-Host $val
            $val++
        }
    下面说明 do While 语句的语法:

        do{<statement list>}while (<condition>)

   示例:
        do{
            Write-Host $val
            $val++
        }while($val -ne 3) 
    下面说明 While 语句的语法:

        while (<condition>){<statement list>}

   示例:
        do
        {
            Write-Host $val
            $val++
        }until($val -gt 3)
 
 
3.1 break
    当 Break 语句出现在如 Foreach、For、Switch 或 While 等循环中时,该 Break 语句将使 
    Windows PowerShell 立即退出该循环。在不循环的 Switch 构造中,Break 语句将使 Windows 
    PowerShell 退出 Switch 代码块。

 

    以下面的 Foreach 语句为例:


        $i=0
        $varB = 10,20,30,40
        foreach ($val in $varB)
        {  
            $i++
            if ($val -eq 30)
            {
                break
            }  
        }
    退出其他循环语句与退出 Foreach 循环的方式完全相同。在以下示例中,在使用 Trap 语句捕获到 
    DivideByZeroException 异常后,Break 语句将使程序退出 While 语句。


        $i = 3
        while ($true)
        {
            trap [DivideByZeroException]
            {
                Write-Host "divide by zero trapped" break
            }
            1 / $i--
        }

    Break 语句可以包含标签。如果将 Break 关键字与标签一起使用,Windows PowerShell 将退出
    带标签的循环而不是退出当前循环。标签的语法如下(此示例演示了 While 循环中的一个标签):


        :myLabel while (<condition>) { <statement list>}


    标签的格式是冒号加您指定的名称。标签必须是语句中的第一个标记,后面必须跟随循环关键字(如 
    While)。
 

    在 Windows PowerShell 中,只有循环关键字(如 Foreach、For 和 While)可以带标签。


    Break 将语句的执行移到带标签的循环之外。在嵌套循环中,这将产生与单用 Break 关键字不同的
    结果。以下结构性示例中的 While 语句含有一个 For 语句:
 

        :myLabel while (<condition 1>)
        {
            for ($item in $items)
            { 
                if (<condition 2>) { break myLabel }
                $item = $x  # A statement inside the For-loop }
        }
    如下面的结构性示例所示,您可以嵌套多个带标签的循环。


        :red while (<condition1>)
        {
            :yellow while (<condition2>)
            {
                while (<condition3>)
                {
                    if ($a) {break}
                    if ($b) {break red}
                    if ($c) {break yellow}
                }
                # After innermost loop
            }
                # After "yellow" loop
        }
                # After "red" loop
3.2 Continue
    在脚本中,Continue 语句使程序流立即返回到由 For、Foreach 或 While 语句控制的最内层循
    环的顶部。
    Continue 关键字支持标签。标签是为脚本语句指定的名称。有关标签的信息,请参阅 
    about_Break。
    在下面的示例中,如果变量 $ctr 等于 5,则程序流返回到 While 循环的顶部。因此,将显示
    从 1 到 10 之间的所有数字(除 5 之外):
    
        while ($ctr -lt 10)
             {
               $ctr +=1
               if ($ctr -eq 5) {continue}
               Write-Host $ctr
             }

 

本文地址:http://www.cnblogs.com/lwme/archive/2010/04/28/1723283.html

内容整理自MSDN:http://technet.microsoft.com/zh-cn/library/dd347616.aspx

令人崩溃的样式-_-