(13)Powershell中的比較運算符與位運算符

上一節介紹了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中的位運算符,可以對文件的屬性進行操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章