首页 > 基础设施 > 正文

PowerShell变量内容为何不能进行比较?

2012-08-21 15:32:46  来源:TechTarget中国

摘要:PowerShell v3临近,本文主要讲解Windows PowerShell Write-Host的使用案例。说明PowerShell变量内容之间的问题。
关键词: PowerShell

    下面是一个简短的代码片段,演示了最常见的一个PowerShell问题:


    $file = Dir C:MyDirectory


    if ($file.name –like '*archive*‘) {


    Write-Host “$($file.name) is an archive”


    }


    这段代码的目的是查看大量的文件,并确定文件名是否含有单词“archive”.不幸的是,这个脚本里有一些经典的错误。


    首先, PowerShell中的Dir命令有可能返回多个对象以及多种类型的对象。当在文件系统驱动器运行时,返回文件和文件夹。在这种情况下,该脚本将是一个不错的命令,因为两个文件和文件夹有一个Name属性($file.name引用名称属性),但是这可能并不是你所希望得到的。在PowerShell v3中,你可以通过添加-File参数限制Dir命令只返回文件。阅读帮助命令查看其他你可以指定的限制。


    第二, 脚本中的$file变量通常包含多个对象,因为文件系统中大部分文件夹包含其他文件夹和多个文件。但这并不总是一个问题,因为PowerShell能很好地把多个对象放到一个变量中。


    下面的比较存在问题:


    if ($file.name –like '*archive*’) {


    你打算用哪个文件的Name属性同“*archive *”比较?在PowerShell v3中,使用 $file.name是完全合法的。深入了解,PowerShell将此命令描述成“我想访问$file变量中所有对象的Name属性。”结果仍是多个对象。在这种情况下,结果包含了多个文件和文件夹的名称的字符串对象。


    问题在于PowerShell的比较运算符,如–like运算符,不能处理多个对象。这些运算符设计用于返回True与False值。如果某些文件命名包含archive而其他没有,返回Maybe值时,运算符该如何做呢?


    解决这个问题的方法是列举文件,因此一次就比较一个。


    对于PowerShell v3,正确方式是:


    $files = Dir C:MyDirectory –File


    foreach ($file in $files) {


    if ($file.name –like '*archive*‘) {


    Write-Host “$($file.name) is an archive”


    }


    }


    Foreach架构目的是接收第二文件($files)中的多个对象,然后每次移动集合中的一个对象。每一次经过,架构从集合中采收一个对象,将其放置在变量的首个专门文件中(例如$file)。以这种方式,你可以每次只运行一个对象。


    虽然使用同个单词的单数与复数很常见,比如$file与$files,但不需要使用Foreach.这样做可让你的代码更易读,但PowerShell不关心这点。


    下面代码也有效:


    $apples = Dir C:MyDirectory –File


    foreach ($fred in $apples) {


    if ($fred.name –like '*archive*’) {


    Write-Host “$($fred.name) is an archive”


    }


    }


    在PowerShell中,有多种方式做任何事。下面的代码也能实现上面的结果:


    Dir C:MyDirectory –File |


    foreach-object {


    if ($_.name –like '*archive*‘) {


    Write-Host “$($_.name) is an archive”


    }


    }


    该种技术使用ForEach-Object cmdlet代替Foreach脚本架构。这个cmdlet使用不同的语法,不用给其具体的变量名称。相反,它给你一个预定的变量($),每次只包含一个对象。两种技术花费的时间都相同,实现的效果都一样。


    你也可以这样做:


    Dir C:MyDirectory –File |


    where-object { $_.name –like '*archive*' } |


    foreach-object {


    Write-Host “$($_.name) is an archive”


    }


    这使用了命令行技术而不是脚本类型的技术,但也完全有效。


    学习PowerShell最困难的地方在于任何任务都有太多有效方式可选。如果你要成功地将其他例子改头换面,貌似你需要懂得所有的实现方式。这种多样性也意味着你能采用你熟悉的方式,平衡你给环境带来的现有技巧。
 


第三十四届CIO班招生
国际CIO认证培训
首席数据官(CDO)认证培训
责编:zhangyexi

免责声明:本网站(http://www.ciotimes.com/)内容主要来自原创、合作媒体供稿和第三方投稿,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证有关资料的准确性及可靠性,读者在使用前请进一步核实,并对任何自主决定的行为负责。本网站对有关资料所引致的错误、不确或遗漏,概不负任何法律责任。
本网站刊载的所有内容(包括但不仅限文字、图片、LOGO、音频、视频、软件、程序等)版权归原作者所有。任何单位或个人认为本网站中的内容可能涉嫌侵犯其知识产权或存在不实内容时,请及时通知本站,予以删除。