PowerShell之Switch语句

来源:互联网 发布:日本 社会问题 知乎 编辑:程序博客网 时间:2024/06/11 13:44

转自http://itecn.net/blogs/ghjconan/archive/2008/03/03/windows-powershell-27-switch.aspx

当脚本专家参加去年11月份的TechED峰会之时,我们抽空离开了自己的展位去聆听Windows PowerShell架构师Jeffrey Snover关于PowerShell的演讲。在他的演讲中,Jeffrey Snover提到一点,PowerShell中最酷最有用的特性之一是Switch语句。不必说,这让脚本专家感到一丝惊讶:在PowerShell所包含的所有特性中最酷最有用的特性之一是switch语句?!?我们发现这有点难以理解。

但是你对switch语句又了解多少呢?Jeffrey很有可能是正确的。

基础的Switch语句

Switch语句与VBScript的Select Case语句很相似:它使你能编写一个从一系列选项中进行选择的脚本,而不是一系列的if语句。例如,考虑以下脚本:

$a = 5

switch ($a)

    {

        1 {"The color is red."}

        2 {"The color is blue."}

        3 {"The color is green."}

        4 {"The color is yellow."}

        5 {"The color is orange."}

        6 {"The color is purple."}

        7 {"The color is pink."}

        8 {"The color is brown."}

        default {"The color could not be determined."}

    }

在这个脚本中我们从将5赋值给名为$a的变量开始。随后我们又建立了一个Switch语句块来访问$a的值并基于该值显示相应的结果。这就是下面这行代码的作用:

switch ($a)

如你所见,我们所做的是插入Switch关键字并在其后跟上将被检测的值(噢,在PowerShell中作为case的替代,被检测值必须被括号括起来)。

接下来的一系列语句都包含在一个脚本块中。(也就是说,都包含在花括号中。)脚本块中的代码是让脚本基于被检测值显示相应的结果。例如,如果$a等于1,那我们将要回显一条消息说明被检测值的颜色是红色。因此,我们使用了以下代码,而具体要回显的信息也包含在花括号中:

1 {"The color is red."}

现在知道它如何工作了吧?你当然也注意到了,在脚本块的结束部分,我们指定了如果没有一句Case处理语句为真时将要回显的信息,(和你在VBScript中使用Case Else一样)。为了达到这个目的,我们只需将想要显示的结果与default条件关联:

default {"The color could not be determined."}

通过以上说明,你就明白了Windows PowerShell switch语句的使用方法。当我们运行先前的脚本时,屏幕上将会回显以下信息:

The color is orange.

在Switch语句中使用通配符

现在,我们知道你在想什么:这很正确,但这不太酷。说的好。但是假设我们告诉你在switch语句中可以使用通配符,这将会改变你认为switch语句不太酷的观点么?

例如,考虑下这个脚本,有人将$a的值设为d14151。我们假设这里的d14151是由字母和数字组合而成的字符串,d意味着该字符串代表黄色。那么我们如何回显被检测的字符串所代表的颜色是黄色,特别是如果我们有一组数字以字母d开头(d14151,d14152,d14153等等)?好的,下面就是解决这个问题的一个方法:

$a = "d14151"

 

switch -wildcard ($a)

    {

        "a*" {"The color is red."}

        "b*" {"The color is blue."}

        "c*" {"The color is green."}

        "d*" {"The color is yellow."}

        "e*" {"The color is orange."}

        "f*" {"The color is purple."}

        "g*" {"The color is pink."}

        "h*" {"The color is brown."}

        default {"The color could not be determined."}

    }

注意我们在这里所做的。首先,我们添加了-wildcard参数;这告诉switch语句当我们访问$a时我们将使用通配符。其次,注意我们在条件语句中使用了星号(一个代表“任意”的通配符):

"a*" {"The color is red."}

这行代码的意义是:“如果$a的值以字母a开头,我们也不关心其后所跟随的字母,可以是任意字符,然后回显被检测值所代表的颜色是红色。”换句话说,如果$a等于a14151,或者$a等于a7777777777,或者$a等于apple,或者$a等于任意以字母a打头的字符串,那么被检测值所代表的颜色是红色。

这真的可行么?我们可以就此和你打赌;我们的字符串以字母d作为打头字母,而我们的脚本将会正确回显它所代表的颜色是黄色:

The color is yellow

顺便说一句,你能在字符串的任意位置放置通配符。当$a中最后一个字母是d时,想要回显相应的语句?那么使用以下命令,即字母d跟随在星号后:

"*d" {"The color is yellow."}

下面是另外一个有趣的通配符。假设,字符串中的首字母与颜色无关。(例如,首字母也许是代表该部件的产地。)而字符串的最后五位字符才决定是什么颜色。那我们怎么从给定的字符串中区分出颜色信息呢?当然像这样:

$a = "d14151"

 

switch -wildcard ($a)

    {

        "?14150" {"The color is red."}

        "?14151" {"The color is blue."}

        "?14152" {"The color is green."}

        "?14153" {"The color is yellow."}

        "?14154" {"The color is orange."}

        "?14155" {"The color is purple."}

        "?14156" {"The color is pink."}

        "?14157" {"The color is brown."}

        default {"The color could not be determined."}

    }

这次我们通过使用问号后跟随五位数字来配置我们的条件语句。这是一个标准的通配符约定:问号代表“任一字符”。换句话说,"?14150" {"The color is red."}表示:“如果$a以任一字符打头,其后跟随14150那么该字符串所代表的颜色是红色。”想知道具体怎么执行?如果$a等于d14151,那么我们的脚本应当返回“the color is blue”。让我们看下结果:

The color is blue.

你知道,当我们越来越多的使用switch语句时,我们就越来越相信它真的很酷。

在Switch语句中使用正则表达式

通配符很棒,但是它们有它们自身的限制;作为对比,很少有正则表达式不能完成的事。例如,假设有一个范围内的字母是表示一种特定的颜色;也就是说,假设任何以字母a,b,c,d开头的字符串所代表的颜色是红色。你能使用通配符来辨别颜色类型么?实话对你说,我们不敢保证。但是我们知道你可以使用正则表达式来决定颜色类型:

$a = "r14151"

 

switch -regex ($a)

    {

        "[a-d]" {"The color is red."}

        "[e-g]" {"The color is blue."}

        "[h-k]" {"The color is green."}

        "[l-o]" {"The color is yellow."}

        "[p-s]" {"The color is orange."}

        "[t-v]" {"The color is purple."}

        "[w-y]" {"The color is pink."}

        "Person" {"The color is brown."}

        default {"The color could not be determined."}

    }

那么这个脚本同我们的通配符脚本的区别是什么?好的,首先,我们使用-regex参数替代-wildcard参数;如同你可能猜测的,该参数告诉switch语句我们将在条件语句中使用正则表达式。然后我们在条件语句中使用了正则表达式。假设我们想要从a,b,c或d中选择出任意一个。在正则表达式中,我们可以通过指定一个字符范围[a-d]来完成这件事。猜下我们的第一个条件语句看上去怎么样?

"[a-d]" {"The color is red."}

很漂亮吧?如果$a被设置为r14151(现在的确是),那么当我们运行以下脚本的时候将得到以下信息:

The color is orange.

让我们使用正则表达式来展示switch语句的另一项特性。让我们假设颜色由字符串的数字个数来表示。换句话说,你能简单的通过统计$a的数字个数来判断颜色类型。一种处理这个问题的方法是(不是最好的方法,提醒下你,但是该方法能满足我们的根本需要):

$a = "14151"

 

switch -regex ($a)

    {

        "\d{8}" {"The color is red."}

        "\d{7}" {"The color is blue."}

        "\d{6}" {"The color is green."}

        "\d{5}" {"The color is yellow."}

        "\d{4}" {"The color is orange."}

        "\d{3}" {"The color is purple."}

        "\d{2}" {"The color is pink."}

        "\d{1}" {"The color is brown."}

        default {"The color could not be determined."}

    }

如你所见(假设你对正则表达式有基本的认识),在第一个条件处是检查$a中是否包含8个连续数字(\d{8})。如果包含,那么脚本将回显“The color is red.” 在第二个条件处是检查$a中是否包含7个连续数字,如此类推。因为$a包含了五位连续数字你也许期待脚本将告诉我们“the color is yellow”。尽管不幸的是,,它告诉我们以下信息:

The color is yellow.

The color is orange.

The color is purple.

The color is pink.

The color is brown.

很可惜。

那么是哪里出错了呢?在VBScript Select Case语句中一旦条件成立那么脚本就会退出Select Case语句,它不再继续检查其它所有条件。但这在PowerShell中不是必然正确的。PowerShell检查$a是否包含五个连续数字,因为它完成了这个检查,所以它回显“the color is yellow”这个消息,这很棒。

但是PowerShell不像VBScript,它不在此处停止下来。相反的它继续检验下一个条件。因为$a也确实包含了四个连续数字,所以脚本也回显了“the color is orange”。PowerShell也不在此处停止。事实上,它忠实地检查了switch语句中的每一个条件。

再次感到遗憾。

在很多时候这个功能是很不错。尤其是像组合数字这样一个值包含能满足多个条件的信息的情况(它包含了五个连续数字那么它所代表的颜色是红色,以字母d开头则意味着它的制造商在Des Moines,等等)。在其它时候,比如这次,我们真心希望PowerShell在找到第一个符合的条件后就能退出switch语句。但是我们如何实现呢?

事实上,这很简单:只需在脚本块中的每一个条件后添加break语句:

$a = "14151"

switch -regex ($a)

    {

        "\d{8}" {"The color is red.”; break}

        "\d{7}" {"The color is blue.”; break}

        "\d{6}" {"The color is green.”; break}

        "\d{5}" {"The color is yellow.”; break}

         "\d{4}" {"The color is orange.”; break}

         "\d{3}" {"The color is purple.”; break}

         "\d{2}" {"The color is pink.”; break}

         "\d{1}" {"The color is brown.”; break}

         default {"The color could not be determined."}

     }

 

这次,当PowerShell找到第一个符合的条件后($a包含五位数字)就会退出。

 在Switch语句中使用数组

让我们再向你展示另一个Switch语句的使用方法,仅仅因为喜欢它。令人感到惊异的是,switch语句实际上能检验数组。换句话说,假设我们拥有以下脚本:

$a = 21, 38, 6

switch ($a)

    {

         1 {"The color is red."}

         2 {"The color is blue."}

         3 {"The color is green."}

         4 {"The color is yellow."}

         5 {"The color is orange."}

         6 {"The color is purple."}

         7 {"The color is pink."}

         8 {"The color is brown."}

     }

 

当我们运行这个脚本时,PowerShell会检查数组$a中的所有对象是否匹配指定的条件。例如,第一个条件是:“如果$a等于1那么颜色是红色。”PowerShell将会检查$a中的三个值(21,38和6)来判断它们中的任意一个是否满足标准。如果找到一个匹配项目,那么脚本将会回显合适的消息。换句话说:

 

The color is purple.

Jeffrey,你是对的:switch语句的确很酷。

下周见。

 

英文原文

http://www.microsoft.com/technet/scriptcenter/resources/pstips/jan08/pstip0111.mspx

已发表 2008年3月3日 17:06 作者 ghjconan
归档在:Weekly Windows PowerShell Tips

原创粉丝点击