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


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


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


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


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


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

比较运算符
说明比较值的例子查找值的列子区分大小写的格式不区分大小写的格式
-eq
等于(equal);查找一个与比较值相等的值(有相等的值就返回该相等的值,否则不返回任何值)

PS C:\> 123 -eq 123

True

PS C:\> "a","b" -eq "a"

a

PS C:\> "a","b" -eq "c"

-ceq-ieq(默认不区分大小写)
-ne不等于(not equal);查找与比较值不相等的值(有不相等的值就返回,否则不返回任何职)PS C:\> 3 -ne 5

True

PS C:\> "a","b" -ne "c"

a

b

-cne-ine(默认不区分大小写)
-gt大于(greater then),条件为真,返回True,否则返回FalsePS C:\> 5 -gt 4

True

PS C:\> 5 -gt 6

False




-ge大于或等于(greater then or equal),条件为真,返回True,否则返回FalsePS C:\> 5 -ge 5

True

PS C:\> 5 -ge 6

False




-lt
小于(less then),条件为真,返回True,否则返回FalsePS C:\> 4 -lt 5

True

PS C:\> 4 -lt 3

False




-le小于或等于(less then or equal),条件为真,返回True,否则返回FalsePS C:\> 4 -le 4

True

PS C:\> 4 -le 3

False




-like模式匹配,判断值与给定的值或是模式是否匹配,可以使用通配符(*)匹配PS C:\> "abc" -like "a"

False

PS C:\> "abc" -like "a*"

True




-notlike
模式不匹配,判断值与给定的值或是模式是否不匹配,可以使用通配符(*)

PS C:\> "abc" -notlike "a"

True

PS C:\> "abc" -notlike "a*"

False




-match使用正则表达式与字符串匹配,当输入标量是,会自动填充Powershell内置变量$MatchesPS C:\> "abc" -match "a"

True

PS C:\> $Matches


Name    Value

----    -----

0       a




-notmatch
使用正则表达式与字符串不匹配,当输入标量是,会自动填充Powershell内置变量$Matches

PS C:\> "abc" -notmatch "a"

False

PS C:\> $Matches


Name   Value

----   -----

0      a




-contains包含运算符,包含一个相同的值(完整的值,而不是值的一部分)。始终返回布尔值PS C:\> "abc","string" -contains "abc"

True

PS C:\> "abc","string" -contains "a"

False




-notcontains包含运算符,不包含一个相同的值(完整的值,而不是值的一部分)。始终返回布尔值PS C:\> "abc","string" -notcontains "abc"

False

PS C:\> "abc","string" -notcontains "a"

True




-replace替换运算符,更改值的指定部分

PS C:\> "abcstring" -replace "abc","123"

123string


-creplace-ireplace( 默认不区分大小写)

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

  1. 包含运算符

    包含运算符(-contains 和 -notcontains)与相等运算符(-eq)比较相似。需要注意的是,包含运算符比较的是整个值,而不是值的一部分,它始终返回布尔值,即使在输入为集合时也如此。

    另外,与相等运算符不同的是,包含运算符在检测到第一个匹配项时立即返回一个值(即类似高级语言中的&&和||,有中断的功能,第一个条件满足,不再判断后续的条件)。但是相等运算符对所有输入进行比较,然后返回集合中的所有匹配项。下面语句说明了 -contains 运算符的功能:

PS C:\> 2,3,4,2 -contains 2
True
PS C:\> "Powershell" -contains "shell"
False
PS C:\> "ab","cd","ef","123" -contains "ab"
True

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

PS C:\> 1,2,3,4,3,2,1 -eq 2
2
2
PS C:\> 1,2,3,4,3,2,1 -contains 2
True

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


2. 匹配运算符

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

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

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

PS D:\MyPowerShell\computer> "Windows","Powershell" -match ".shell"
Powershell
PS D:\MyPowerShell\computer> ( Get-Command Get-Member -Syntax ) -match "-View"
True
PS D:\MyPowerShell\computer> ( Get-Command Get-Member -Syntax ) -notmatch "-path"
True
PS D:\MyPowerShell\computer> ( Get-Content servers.txt ) -match "^computer\d"
computer1
computer2

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

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

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

PS D:\> "Monday","Tuesday","Friday" -match "fri"
Friday
PS D:\> $Matches
PS D:\>

    但是如果向匹配运算符提交一个单字符串(左侧参数)。-match 运算符返回布尔值并填充 $Matches 自动变量。例如:

PS D:\> "Monday" -match "mon"
True
PS D:\> $Matches

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

    -notmatch 运算符在输入是标量(左侧参数是多个值)且结果为 False 时(也就是说,当它检测到匹配项时)填充 $Matches 自动变量。例如:

PS D:\> "Monday"  -notmatch "tmon"
True
PS D:\> $Matches
PS D:\>
PS D:\> "Monday"  -notmatch "mon"
False
PS D:\> $Matches

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

3. 替换运算符

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

Get-ChildItem | Rename-Item -NewName { $_ -replace '.txt$','.log$' }

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

<input> <operator> <original>, <substitute>

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

PS D:\> "Hello" -replace "H","h"
hello
PS D:\> "Hello" -ireplace "H","h"
hello
PS D:\> "hello" -creplace "H","F"
hello

4. 位运算符

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

PowerShell 支持以下位运算符

运算符
说明例子
-band
位与(bianry and),两个输入都为1时,结果为1,否则为0(同真为真,否则为假)PS D:\> 2 -band 1

0

-bor位或(binary or),两个输入都为0时,结果为0,否则为1(同假为假,否则为真)PS D:\> 2 -bor 1

3

-bxor
位异或,两个输入不同时为1,相同时为0(相异为真,否则为假)PS D:\> 2 -bxor 1

3

    位运算符是对二进制格式值执行运算(将输入的值转换为二进制后再运算,最后将结果转换为十进制显示)。例如,数字 2 的二进制是 10 ,数字 1 的二进制是 01,所以上表中的例子实际进行的是如下运算

位与(-band)位或(-bor)位异或(-bxor)
10   (2)

01   (1)

----------位与

00   (0)

10   (2)

01   (1)

----------位或

11   (3)

10   (2)

01   (1)

----------位异或

11   (3)

    对于其他的运算符都很好理解,它们确实可以解决开发和管理中的很多任务。

    问题是,Powershell中的位运算符有什么用 ?或者是Powershell 为什么要支持位运算符 ?

或许你从上面的例子中已经发现,位运算符可以把某些位设置为1(表示有值),把某些位设置为0(表示没值)。 一个比较好的例子是利用位运算符可以对文件或文件夹的是否具有某一属性进行判断,或是设置,或是移除。

    

    在开始例子之前,先了解下 [System.IO.FileAttributes] 对文件和文件夹提供了以下属性(成员)。

属性名二进制值十进制值
ReadOnly11
Hidden102
System1004
Directory1000016
Archive10000032
Device100000064
Normal10000000128
Temporary100000000256
SparseFile1000000000512
Compressed100000000002048
Offline1000000000004096
Encrypted100000000000016384

    表中标出的部分是比较常见和熟悉的,比如ReadOnly,Hidden。添加属性相当于是将二进制值进行相加。 比如你想给某个文件添加只读(ReadOnly)和隐藏(Hidden)属性,实际上是"1"+"11"="11"或是3(十进制)。


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

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

PS D:\MyPowerShell\computer> $file = Get-ChildItem . test.txt -Force
PS D:\MyPowerShell\computer> $file.Attributes
ReadOnly, Hidden
PS D:\MyPowerShell\computer> if( $file.Attributes -band [System.IO.FileAttributes]::Hidden )
>> {
>>     Write-Host "Hidden Attribute Set"
>> }
>>
Hidden Attribute Set

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


4.2 位运算符设置文件属性

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

PS D:\MyPowerShell\computer> $file = Get-ChildItem . test.txt -Force
PS D:\MyPowerShell\computer> $file.Attributes
ReadOnly, Hidden
PS D:\MyPowerShell\computer> $file.Attributes = ( $file.Attributes -bor [System.IO.FileAttributes]::System )
PS D:\MyPowerShell\computer> $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 D:\MyPowerShell\computer> $file = Get-ChildItem . test.txt -Force
PS D:\MyPowerShell\computer> $file.Attributes
ReadOnly, Hidden, System
PS D:\MyPowerShell\computer> $file.Attributes = ( $file.Attributes -bxor [System.IO.FileAttributes]::System )
PS D:\MyPowerShell\computer> $file.Attributes
ReadOnly, Hidden
PS D:\MyPowerShell\computer> $file.Attributes = ( $file.Attributes -bxor [System.IO.FileAttributes]::System )
PS D:\MyPowerShell\computer> $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 D:\MyPowerShell\computer> $file = Get-ChildItem . test.txt -Force
PS D:\MyPowerShell\computer> $file.Attributes
ReadOnly, Hidden, System
PS D:\MyPowerShell\computer> if( $file.Attributes -band [System.IO.FileAttributes]::System )
>> {
>>     $file.Attributes = ( $file.Attributes -bxor [System.IO.FileAttributes]::System )
>> }
>> $file.Attributes
>>
ReadOnly, Hidden



总结

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