zhang-snail

导航

 

(13)Powershell中的比较运算符与位运算符

上一节介绍了Powershell中变量的类型,详细内容使劲戳这里


本节介绍Powershell中的比较运算符。


使用比较运算符,可以指定用于比较值,也可以查找与指定模式匹配的值。如果要使用比较运算符,需要同时指定要进行比较的值以及分隔这些值的运算符。

默认情况下,所有比较运算符都不区分大小写。如果要使一个比较运算符区分大小写,需要在运算符名称前加字母"c"。例如,"-eq"区分大小写的形式为"-ceq"。如果要明确表示不区分大小写,则在运算符前加字母"i"。例如,"-eq"的明确不区分大小写的形式为"-ieq"。

除了包含运算符(-contains、-notcontains)和类型运算符(-is、-isnot),其它的所有比较运算符在运算符的输入(运算符左侧的值)是单个值(标量)时,都将返回一个布尔值(True或者False)。当输入是值的集合时,包含运算符和类型运算符将返回任何匹配值。如果集合中没有匹配项,则这些运算符不返回任何值。包含运算符和类型运算符始终返回布尔值。

Powershell中支持以下比较运算符。




以下是使用这些比较运算符时需要注意的一些细节。

  1. 包含运算符
    包含运算符(-contains 和 -notcontains)与相等运算符(-eq)比较相似。需要注意的是,包含运算符比较的是整个值,而不是值的一部分,它始终返回布尔值,即使在输入为集合时也如此。
    另外,与相等运算符不同的是,包含运算符在检测到第一个匹配项时立即返回一个值(即类似高级语言中的&&和||,有中断的功能,第一个条件满足,不再判断后续的条件)。但是相等运算符对所有输入进行比较,然后返回集合中的所有匹配项。下面语句说明了 -contains 运算符的功能:
PS C:\Windows\System32\WindowsPowerShell\v1.0> 2,3,4,2 -contains 2
True

PS C:\Windows\System32\WindowsPowerShell\v1.0> "Powershell" -contains "shell"
False

PS C:\Windows\System32\WindowsPowerShell\v1.0> "ab","cd","ef","123" -contains "ab"
True

下面的语句说明了包含运算符与等于运算符的不同。等于运算符会比较所有的值,返回所有的匹配项,包含运算符在遇到第一个匹配项时返回一个 TRUE 值。

PS C:\Windows\System32\WindowsPowerShell\v1.0> 1,2,3,4,3,2,1 -eq 2
2
2

PS C:\Windows\System32\WindowsPowerShell\v1.0> 1,2,3,4,3,2,1 -contains 2
True

所以在输入的集合很大时,-contains 运算符返回结果的速度比等于运算符快。



  1. 匹配运算符
    匹配运算符(-match 和 -notmatch)使用正则表达式来查找与指定模式匹配或不匹配的元素。语法如下:

<string[]> -match
<string[]> -notmatch


例如,以下是 -match 运算符的例子,其中servers.txt 中有两行,分别为computer1 和 computer2 :

PS C:\Windows\System32\WindowsPowerShell\v1.0> "Windows","Powershell" -match ".shell"
Powershell

PS C:\Windows\System32\WindowsPowerShell\v1.0>  ( Get-Command Get-Member -Syntax ) -match "-View"
True

PS C:\Windows\System32\WindowsPowerShell\v1.0> ( Get-Command Get-Member -Syntax ) -notmatch "-path"
True

PS C:\Windows\System32\WindowsPowerShell\v1.0> ( Get-Content servers.txt ) -match "^computer\d"
computer1
computer2

匹配运算符仅在字符串中搜索。无法在整数数组(可以利用循环进行比较来搜索)或其他对象中搜索。

当运算符的输入(左侧参数)是一个单标量对象时,-match 和 -notmatch 运算符填充 $Matches 自动变量。当输入是标量(多个值)时,-match 和 notmatch 运算符返回布尔值,并将 $Matches 自动变量的值设置为参数的匹配项目。如果输入是一个集合,则 -match 和 -notmatch 运算符返回该集合中的匹配成员,但运算符不会填充 $Matches 变量。

例如,以下语句将一个字符串集合提交给 -match 运算符。-match 运算符将返回集合中的匹配项目。它不会填充 $Matches 自动变量。

PS C:\Windows\System32\WindowsPowerShell\v1.0> "Monday","Tuesday","Friday" -match "fri"
Friday

PS C:\Windows\System32\WindowsPowerShell\v1.0> $Matches

PS C:\Windows\System32\WindowsPowerShell\v1.0> 

但是如果向匹配运算符提交一个单字符串(左侧参数)。-match 运算符返回布尔值并填充 $Matches 自动变量。例如:
PS C:\Windows\System32\WindowsPowerShell\v1.0> "Monday" -match "mon"
True

PS C:\Windows\System32\WindowsPowerShell\v1.0> $Matches

Name                           Value                                                                                                                 
----                           -----                                                                                                                 
0                              Mon                                                                                                                   

-notmatch 运算符在输入是标量(左侧参数是多个值)且结果为 False 时(也就是说,当它检测到匹配项时)填充 $Matches 自动变量。例如:
PS C:\Windows\System32\WindowsPowerShell\v1.0> "Monday"  -notmatch "tmon"
True

PS C:\Windows\System32\WindowsPowerShell\v1.0> $Matches

PS C:\Windows\System32\WindowsPowerShell\v1.0> "Monday"  -notmatch "mon"
False

PS C:\Windows\System32\WindowsPowerShell\v1.0> $Matches

Name                           Value                                                                                                                 
----                           -----                                                                                                                 
0                              Mon                                                                                                                   


  1. 替换运算符
    -replace 运算符可通过正则表达式用指定值替换某个值的全部或部分。这个运算在进行批量任务时非常有用,如批量替换文件中指定的内容,批量重命名文件等,例如,以下语句将当前路径下所有 .txt 文件的文件扩展名更改为.log:
 Get-ChildItem | Rename-Item -NewName {$_ -replace '.txt$','.log$' }

-replace 运算符的语法如下,其中, 占位符表示要被替换的字符,而 占位符表示想要替换成的字符:
<input> <operator> <original>, <substitute>

默认情况下,-replace 运算符不区分大小写。如果要使它区分大小写,请使用 -creplace。要明确表示它不区分大小写,请使用 ireplace。例如:

PS C:\Windows\System32\WindowsPowerShell\v1.0> "Hello" -replace "H","h"
hello

PS C:\Windows\System32\WindowsPowerShell\v1.0> "Hello" -ireplace "H","h"
hello

PS C:\Windows\System32\WindowsPowerShell\v1.0> "hello" -creplace "H","F"
hello


4. 位运算符
PowerShell 支持标准位运算符,包括位与运算符 (-band) 以及位或和位异或运算符(-bor 和 -bxor)。从 Windows PowerShell 2.0 开始,所有位运算符都使用 64 位整数。

PowerShell 支持以下位运算符



4.1 位运算符判断文件的属性是否有设置

比如现在有一个文件servers.txt具有 ReadOnly 和 Hidden 属性(可以右击文件,选择属性,勾选只读和隐藏属性,可以点击高级,不勾选"可以存档文件(A)",点击应用),下面的语句判断该文件的隐藏属性是否有设置:

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file = Get-ChildItem . servers.txt -Force

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes
ReadOnly, Hidden

PS C:\Windows\System32\WindowsPowerShell\v1.0>  if( $file.Attributes -band [System.IO.FileAttributes]::Hidden )
 {
     Write-Host "Hidden Attribute Set"
 }
Hidden Attribute Set

PS C:\Windows\System32\WindowsPowerShell\v1.0> 

根据上表的内容可知,文件的 ReadOnly,Hidden 属性的二进制是 "11",Hidden 属性的二进制是 "10",所以上面语句中 if 语句实际上进行的判断是 if( 11 -band 10 ),所以结果是二进制 "10", 根据上表的内容可知是 Hidden,所以输出是Hidden属性已设置。

4.2 位运算符设置文件属性

继续使用上面具有 ReadOnly 和 Hidden 属性的文件,这里通过位运算符给该文件设置 System 属性。 语句如下:

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file = Get-ChildItem . servers.txt -Force

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes
ReadOnly, Hidden

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes = ( $file.Attributes -bor [System.IO.FileAttributes]::System )

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes
ReadOnly, Hidden, System

同样根据之前的表格可知,文件的 ReadOnly,Hidden 属性的二进制是 "11",System 属性的二进制是 "100",所以上面语句中 $file.Attributes 赋值语句实际上进行的是 ( 11 -bor 100 ),所以结果是二进制 "111", 根据上表的内容可知是 ReadOnly, Hidden, System 二进制属性之和,表示这三个属性都已设置,所以输出是结果是ReadOnly, Hidden, System。


4.3 位运算符移除文件的属性

继续使用之前具有 ReadOnly 和 Hidden 属性的文件,重复运行下面的语句设置可以设置(打开)System属性或去掉(关闭)System属性。

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file = Get-ChildItem . servers.txt -Force

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes
ReadOnly, Hidden, System

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes = ( $file.Attributes -bxor [System.IO.FileAttributes]::System )

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes
ReadOnly, Hidden

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes = ( $file.Attributes -bxor [System.IO.FileAttributes]::System )

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes
ReadOnly, Hidden, System

第一次运行 $file.Attributes = ( $file.Attributes -bxor [System.IO.FileAttributes]::System ) 时,相当于执行的是$file.Attributes = ( 111 -bxor 100 ),结果是二进制的 "011",即输出结果的ReadOnly,Hidden,再次运行时,相当于执行的是 $file.Attributes = ( 011 -bxor 100 ),结果是二进制的 "111",即输出结果的 ReadOnly, Hidden, System 。

从这个例子可以看出,利用位运算符可以设置当前属性的对立面(打开或关闭),如果要去掉文件的某个属性,则需要先判断文件的属性是否已设置,如果存在,则去掉该属性。例如

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file = Get-ChildItem . servers.txt -Force

PS C:\Windows\System32\WindowsPowerShell\v1.0> $file.Attributes
ReadOnly, Hidden, System

PS C:\Windows\System32\WindowsPowerShell\v1.0> if( $file.Attributes -band [System.IO.FileAttributes]::System )
 {
     $file.Attributes = ( $file.Attributes -bxor [System.IO.FileAttributes]::System )
 }
 $file.Attributes
ReadOnly, Hidden


总结

通过本节内容的学习,应当掌握Powershell中的比较运算符使用,以及注意事项,比如命令是否区分大小写。另外需要注意,通过Powershell中的位运算符,可以对文件的属性进行操作。

posted on 2024-01-21 12:42  zhang-snail  阅读(52)  评论(0编辑  收藏  举报