我如何使用开关?

时间:2018-05-18 16:37:29

标签: powershell switch-statement

这是为了帮助任何遇到理解和使用switch语句的人,包括在循环中使用切换,这通常是PowerShell用户的跳闸点。

我的问题如下:

  • 如何使用交换机支持的不同参数和案例?
    • -Exact-Regex-Wildcard-CaseSensitive-File
    • stringnumbervariable{expression}
  • 为什么breakcontinue在循环中的case语句中不起作用?

    while ($true) {
        switch ($eval) {
            'some condition' { continue }
            default {
                break
            }
        }
    }
  • 我有default case,但它没有做任何事情?

    switch ($eval) {
        'default' { 'this should do a thing!' }
    }

1 个答案:

答案 0 :(得分:0)

switch语句有许多不同的用例,但它们最终用于使代码比宏if-elseif-else链更具可读性。

switch接受条件(或条件数组),并尝试将其与作者提供的案例进行匹配。这个条件可以是任何值。

有关PowerShell开关的一个重要注意事项,因为它们可以采用一系列条件,它们是功能循环,因此可以标记它们(:mySwitch switch ())和break / continue个关键字对他们起作用。将针对每个案例评估一个参数,除非它遇到breakcontinue语句,default仅适用于没有案例匹配的情况。

  • 如何使用交换机支持的不同参数和案例?

使用-File参数时,切换逐行扫描文件。在这个用例中,它基本上运行switch (Get-Content -Path $filePath)而不是传递条件:

switch -File $filePath {

这四个参数会影响string个案例的匹配方式:-Exact(默认),-Regex-Wildcard(这三个是彼此独占的,最后一个是使用了一行,最后是-CaseSensitive。这些参数中的每一个都类似于比较运算符-eq-match-like-CaseSensitive使其成为-ceq-cmatch-clike如果参数不是字符串,则 不适用于它。这些参数在条件之前传递:

switch -Regex -CaseSensitive ($eval) {

switch -Wildcard -File C:\Temp\myfile.txt {

我认为string匹配应该相当明显,因为我的上述描述与比较运算符相关,所以我不会进一步讨论它们。

我对$variable个案并没有太多用处,也没有很好的记录。当试图为了这个答案的目的探索这个时,我试图与[pscustomobject]类型进行比较时遇到了冻结的控制台,所以YMMV。

Number支持小数,有符号和无符号整数,例如:

switch (1.3) {
    1.3 { 'this' }
    default { 'that' }
}
# "this"

switch (-5) {
    -5 { 'that' }
    default { 'this' }
}
# "that"

我使用doubleintuint64对此进行了测试。

支持的最后一个案例是expression和我最喜欢的一个案例。当您传递要由交换机评估的表达式时,它类似于使用管道。您可以使用$_(或$PSItem)访问该对象,并且其成员可以照常访问。例如:

switch (Get-WmiObject -Class Win32_OperatingSystem) {
    {$PSItem.Caption -like '*server*'} {
        "You're on a server OS!"
    }
    {$PSItem.Organization} { # truthy evaluation
        "You're part of organization: $($PSItem.Organization)!"
    }
    default {
        "This can't possibly fail!"
    }
}
  • 为什么breakcontinue在循环中的case语句中不起作用?

因为switch的函数类似于循环,所以这些关键字对switch的块而不是封装循环起作用。要超越此限制,您需要使用循环标签:

:myLoop while ($true) {
    :mySwitch switch ($eval) {
        'some condition' { continue }
        default {
            break
        }
    }
}

在这两种情况下,这将是breakcontinue switch,而不是while循环。为了控制,您需要指定您指定的标签,例如:

:myLoop while ($true) {
    :mySwitch switch ($eval) {
        #if $eval is an array, goes to the next iteration
        'some condition' { continue mySwitch } 
        default {
            break myLoop
        }
    }
}
  • 我有default case,但它没有做任何事情?

这个归结为一个错字。 default关键字,如果您有'default',则为string评估。因此,在示例中,请通过删除default 关键字周围的引号来解决此问题。

switch ($eval) {
    default { 'this now does a thing!' }
}