簡短描述
PowerShell 中的比較運算符可以比較兩個值或篩選集合元素與輸入值。
完整描述
比較運算子可讓您比較符合指定模式的值或尋找值。 PowerShell 包含下列比較運算子:
相等
-
-eq-ieq-ceq、 - 等於 -
-ne-ine-cne、 - 不等於 -
-gt-igt、-cgt- 大於 -
-ge-ige-cge、 - 大於或等於 -
-lt-ilt-clt、 - 小於 -
-le-ile-cle、 - 小於或等於
比對
-
-like、 --ilike-clike字串符合通配符模式 -
-notlike、 --inotlike-cnotlike字串不符合通配符模式 -
-match、 --imatch-cmatch字串符合 regex 模式 -
-notmatch、 --inotmatch-cnotmatch字串不符合 regex 模式
取代
-
-replace、-ireplace--creplace尋找並取代符合 regex 模式的字串
遏制
-
-contains-icontains-ccontains、 - 集合包含值 -
-notcontains-inotcontains-cnotcontains、 - 集合不包含值 -
-in、-iin、-cin- 值位於集合中 -
-notin、-inotin、-cnotin- 值不在集合中
類型
-
-is- 這兩個物件都是相同的類型 -
-isnot- 物件的類型不相同
共同特點
除非您使用明確區分大小寫的運算符,否則字串比較不區分大小寫。 若要區分大小寫比較運算子,請在 之後c新增 - 。 例如, -ceq 是 區分大小寫的版本 -eq。
若要明確區分大小寫,請在 之後i新增 - 。 例如, -ieq 是的明確不區分大小寫版本 -eq。
字串比較會針對區分大小寫和不區分大小寫的比較使用 InvariantCulture 。 比較位於 Unicode 字碼點之間,且不會使用文化特性特定的定序順序。 無論目前的文化特性為何,結果都是相同的。
當比較表達式中的左側值是 純 量值時,運算符會 傳回布爾 值。 當表達式中的左側值是集合時,運算符會傳回符合表達式右手值之集合的專案。 右側值一律會被視為單一實例,即使它們是集合也一樣。 比較運算子無法有效地比較集合與集合。
如果集合中沒有相符項目,比較運算符會傳回空數位列。 例如:
$a = (1, 2) -eq 3
$a.GetType().Name
$a.Count
Object[]
0
但也有一些例外:
- 內含專案和類型運算元一律會傳 回布爾 值
- 運算符
-replace會傳回取代結果 -
-match和-notmatch運算子也會填入自動變數,$Matches除非表達式左邊是集合。
等號比較運算子
-eq 和 -ne
當左側為純量時,如果右側相等, -eq 則會傳回 True , -eq 否則會傳 回 False。
-ne會執行相反的動作;當雙方相等時,它會傳回 False;否則會傳-ne。
範例:
2 -eq 2 # Output: True
2 -eq 3 # Output: False
'abc' -eq 'abc' # Output: True
'abc' -eq 'abc', 'def' # Output: False
'abc' -ne 'def' # Output: True
'abc' -ne 'abc' # Output: False
'abc' -ne 'abc', 'def' # Output: True
當左側是集合時, -eq 傳回符合右側的成員,同時 -ne 篩選掉它們。
範例:
1,2,3 -eq 2 # Output: 2
'abc', 'def' -eq 'abc' # Output: abc
'abc', 'def' -ne 'abc' # Output: def
這些運算子會處理集合的所有元素。 範例:
'zzz', 'def', 'zzz' -eq 'zzz'
zzz
zzz
相等運算子可以比較不同類型的物件。 請務必了解比較右側的值可以轉換成左側值的型別進行比較。
例如,字串 '1.0' 會轉換成要與 值 1比較的整數。 這個範例會傳 True回 。
PS> 1 -eq '1.0'
True
在此範例中,值 1 會轉換成要與字串 比較的字串 '1.0'。 這個範例會傳 False回 。
PS> '1.0' -eq 1
False
等號運算元接受任兩個物件,而不只是純量或集合。 但比較結果不保證對用戶有意義。 下列範例示範此問題。
class MyFileInfoSet {
[string]$File
[int64]$Size
}
$a = [MyFileInfoSet]@{File = 'C:\Windows\explorer.exe'; Size = 4651032}
$b = [MyFileInfoSet]@{File = 'C:\Windows\explorer.exe'; Size = 4651032}
$a -eq $b
False
在此範例中,我們建立了兩個具有相同屬性的物件。 然而,相等測試結果是 False ,因為它們是不同的物件。 若要建立可比較的類別,您必須在類別中實 作 System.IEquatable<T> 。 下列範例示範實作 System.IEquatableT< 且具有兩個屬性 > File 和 Size 的 MyFileInfoSet 類別的部分實作。 如果兩個 Equals() 物件的 File 和 Size 屬性相同,此方法會傳回 True。
class MyFileInfoSet : System.IEquatable[Object] {
[string]$File
[int64]$Size
[bool] Equals([Object] $obj) {
return ($this.File -eq $obj.File) -and ($this.Size -eq $obj.Size)
}
}
$a = [MyFileInfoSet]@{File = 'C:\Windows\explorer.exe'; Size = 4651032}
$b = [MyFileInfoSet]@{File = 'C:\Windows\explorer.exe'; Size = 4651032}
$a -eq $b
True
比較任意物件的一個突出範例是找出其是否為 Null。 但是,如果您需要判斷變數是否為 $null,則必須放在 $null 等號運算子的左側。 把它放在右側不會做你預期的事。
例如,讓我們 $a 成為包含 null 元素的陣列:
$a = 1, 2, $null, 4, $null, 6
下列不是 Null 的測試 $a 。
$null -ne $a
True
不過,下列檔案器會從 $a中取出所有 Null 元素:
$a -ne $null # Output: 1, 2, 4, 6
1
2
4
6
-gt、-ge、-lt 和 -le
-gt、 -ge、 -lt和 -le 的行為非常類似。 當兩端都是純量時,會根據雙方的比較方式傳回 True 或 False :
| 操作員 | 傳回 True 時... |
|---|---|
-gt |
左側更大 |
-ge |
左側大於或等於 |
-lt |
左側較小 |
-le |
左側較小或等於 |
在下列範例中,所有語句都會傳回 True。
8 -gt 6 # Output: True
8 -ge 8 # Output: True
6 -lt 8 # Output: True
8 -le 8 # Output: True
注意
在大部分的程式設計語言中,大於 運算子是 >。 在 PowerShell 中,此字元用於重新導向。 如需詳細資訊,請參閱 about_Redirection。
當左側是集合時,這些運算符會比較集合的每個成員與右側。 根據其邏輯,他們會保留或捨棄成員。
範例:
$a=5, 6, 7, 8, 9
Write-Output 'Test collection:'
$a
Write-Output "`nMembers greater than 7"
$a -gt 7
Write-Output "`nMembers greater than or equal to 7"
$a -ge 7
Write-Output "`nMembers smaller than 7"
$a -lt 7
Write-Output "`nMembers smaller than or equal to 7"
$a -le 7
Test collection:
5
6
7
8
9
Members greater than 7
8
9
Members greater than or equal to 7
7
8
9
Members smaller than 7
5
6
Members smaller than or equal to 7
5
6
7
這些運算符會使用任何實作 System.IComparable 的類別。
範例:
# Date comparison
[datetime]'2001-11-12' -lt [datetime]'2020-08-01' # True
# Sorting order comparison
'a' -lt 'z' # True; 'a' comes before 'z'
'macOS' -ilt 'MacOS' # False
'MacOS' -ilt 'macOS' # False
'macOS' -clt 'MacOS' # True; 'm' comes before 'M'
下列範例示範美國 QWERTY 鍵盤上沒有符號,且在 『a' 之後排序。 它會將包含所有這類符號的集合饋送給 -gt 運算符,以將它們與 『a』 進行比較。 輸出是空陣列。
$a=' ','`','~','!','@','#','$','%','^','&','*','(',')','_','+','-','=',
'{','}','[',']',':',';','"','''','\','|','/','?','.','>',',','<'
$a -gt 'a'
# Output: Nothing
如果運算子的兩端無法合理比較,這些運算子就會引發非終止錯誤。
比對運算子
比對運算子 (-like、 -notlike-match和 -notmatch) 會尋找符合或不符合指定模式的專案。 和 -like 的模式-notlike是通配符表達式(包含 *、 ?和 [ ]),而 -match 接受-notmatch正則表示式 (regex)。
語法為:
<string[]> -like <wildcard-expression>
<string[]> -notlike <wildcard-expression>
<string[]> -match <regular-expression>
<string[]> -notmatch <regular-expression>
當這些運算子的輸入是純量值時,它們會傳回 布爾 值。
當輸入是值的集合時,集合中的每個項目都會轉換成字串以進行比較。
-match和 -notmatch 運算符會分別傳回任何相符和不相符的成員。 不過,和 -like 運算符會將-notlike成員當做字串傳回。 為集合 -like 成員傳回的字串,是 -notlike 用於比較的運算符字串,而且是透過將成員轉換成字串來取得的字串串。
-like 和 -notlike
-like 和 -notlike 的行為類似於 -eq 和 -ne,但右側可能是包含 通配符的字串。
範例:
'PowerShell' -like '*shell' # Output: True
'PowerShell' -notlike '*shell' # Output: False
'PowerShell' -like 'Power?hell' # Output: True
'PowerShell' -notlike 'Power?hell' # Output: False
'PowerShell' -like 'Power[p-w]hell' # Output: True
'PowerShell' -notlike 'Power[p-w]hell' # Output: False
'PowerShell', 'Server' -like '*shell' # Output: PowerShell
'PowerShell', 'Server' -notlike '*shell' # Output: Server
為了獲得最佳結果,和 -like 運算符的-notlike右側應該是包含通配符表達式的字串常值。 PowerShell 會將通配符表達式傳遞至通配符表達式剖析器。 若要比對其中一個通配符(*、 ?或 [ ]),您必須使用反引號字元來`逸出它。 例如,若要比對常值 ?,請在 `? 通配符表示式中使用 。 如果您使用可展開的字串表達式PowerShell會在將字串傳遞至通配符剖析器之前展開字串,這會導致未逸出的字元傳送為通配符。
# Escaped literals in an expandable string
PS> "f`?`?"
f??
# Escaped literals in a literal string
PS> 'f`?`?'
f`?`?
# Comparison containing 2 wildcards
PS> 'f??' -like 'f??'
True
PS> 'for' -like 'f??'
True
# Comparison containing literal '?' characters
PS> 'f??' -like 'f`?`?'
True
PS> 'for' -like 'f`?`?'
False
-match 和 -notmatch
-match 並使用 -notmatch 正則表示式來搜尋左側值的模式。 正則表示式可以比對複雜模式,例如電子郵件位址、UNC 路徑或格式化的電話號碼。 右側字串必須遵守 正則表達式 規則。
純量範例:
# Partial match test, showing how differently -match and -like behave
'PowerShell' -match 'shell' # Output: True
'PowerShell' -like 'shell' # Output: False
# Regex syntax test
'PowerShell' -match '^Power\w+' # Output: True
'bag' -notmatch 'b[iou]g' # Output: True
如果輸入是集合,運算符會傳回該集合的相符成員。
集合範例:
'PowerShell', 'Super PowerShell', 'Power's hell' -match '^Power\w+'
# Output: PowerShell
'Rhell', 'Chell', 'Mel', 'Smell', 'Shell' -match 'hell'
# Output: Rhell, Chell, Shell
'Bag', 'Beg', 'Big', 'Bog', 'Bug' -match 'b[iou]g'
#Output: Big, Bog, Bug
'Bag', 'Beg', 'Big', 'Bog', 'Bug' -notmatch 'b[iou]g'
#Output: Bag, Beg
-match 和 -notmatch 支援 regex 擷取群組。 每次在純量輸入上執行, -match 而結果為 True,或 -notmatch 結果為 False 時,都會覆寫 $Matches 自動變數。
$Matches
是哈希表,一律具有名為 『0』 的索引鍵,其會儲存整個相符專案。
如果正則表達式包含擷取群組, $Matches 則包含每個群組的其他索引鍵。
請務必注意, $Matches 哈希表只包含第一個相符模式。
範例:
$string = 'The last logged on user was CONTOSO\jsmith'
$string -match 'was (?<domain>.+)\\(?<user>.+)'
$Matches
Write-Output "`nDomain name:"
$Matches.domain
Write-Output "`nUser name:"
$Matches.user
True
Name Value
---- -----
domain CONTOSO
user jsmith
0 was CONTOSO\jsmith
Domain name:
CONTOSO
User name:
jsmith
-match當結果為 False-notmatch,或輸入為集合時,不會覆寫自動變數。 因此,如果尚未設定變數, $null 則會包含先前設定的值。 在叫用其中一個運算符之後參考 $Matches 時,請考慮使用 condition 語句來確認目前運算符調用已設定變數。
範例:
if ('<version>1.0.0</version>' -match '<version>(.*?)</version>') {
$Matches
}
如需詳細資訊,請參閱 about_Regular_Expressions 和 about_Automatic_Variables。
替代運算子
以正則表達式取代
如同 -match, -replace 運算子會使用正則表達式來尋找指定的模式。 但不同於 -match,它會以另一個指定的值取代相符專案。
語法:
<input> -replace <regular-expression>, <substitute>
運算子會使用正規表示式,將值的所有或部分取代為指定的值。 您可以針對許多系統管理工作使用 運算符,例如重新命名檔案。 例如,下列命令會將所有 .txt 檔案的擴展名變更為 .log:
Get-ChildItem *.txt | Rename-Item -NewName { $_.Name -replace '\.txt$','.log' }
根據預設, -replace 運算子不區分大小寫。 若要區分大小寫,請使用 -creplace。 若要明確區分大小寫,請使用 -ireplace。
範例:
'book' -ireplace 'B', 'C' # Case insensitive
'book' -creplace 'B', 'C' # Case-sensitive; hence, nothing to replace
Cook
book
從 PowerShell 7.2 開始,當運算符語句中的 -replace 左側操作數不是字串時,該操作數會轉換成字串。
PowerShell 會執行不區分文化特性的字串轉換。
例如,如果您的文化特性設定為法文(fr),則區分文化特性的字串轉換值為 1.21,2。
在 PowerShell 7.2 之前:
PS> [cultureinfo]::CurrentCulture = 'fr'
PS> 1.2 -replace ','
12
在 PowerShell 7.2 和更新版本中:
PS> [cultureinfo]::CurrentCulture = 'fr'
PS> 1.2 -replace ','
1.2
正則表達式替代
您也可以使用正則表示式,使用擷取群組和替代來動態取代文字。 擷取群組可以在群組識別碼之前使用貨幣符號 (<substitute>) 字元在$字串中參考。
在下列範例中 -replace ,運算符會接受 格式 DomainName\Username 的用戶名稱,並轉換成 Username@DomainName 格式:
$SearchExp = '^(?<DomainName>[\w-.]+)\\(?<Username>[\w-.]+)$'
$ReplaceExp = '${Username}@${DomainName}'
'Contoso.local\John.Doe' -replace $SearchExp, $ReplaceExp
John.Doe@Contoso.local
警告
此 $ 字元在 PowerShell 和正規表示式中都有語法角色:
- 在 PowerShell 中,在雙引號之間,它會指定變數,並做為子表達式運算符。
- 在 Regex 搜尋字串中,它表示行尾。
- 在 Regex 替代字串中,其表示擷取的群組。 請務必將正則表示式放在單引號之間,或插入反引號字元
`之前。
例如:
$1 = 'Goodbye'
'Hello World' -replace '(\w+) \w+', "$1 Universe"
# Output: Goodbye Universe
'Hello World' -replace '(\w+) \w+', '$1 Universe'
# Output: Hello Universe
$$ 在 Regex 中表示常值 $。 在替代字串中,這會 $$ 在產生的取代中包含常值 $ 。 例如:
'5.72' -replace '(.+)', '$ $1' # Output: $ 5.72
'5.72' -replace '(.+)', '$$$1' # Output: $5.72
'5.72' -replace '(.+)', '$$1' # Output: $1
若要深入瞭解,請參閱正則表達式中的about_Regular_Expressions和替代。
替代集合中的
<input>當 對 -replace 運算子是集合時,PowerShell 會將取代套用至集合中的每個值。 例如:
'B1','B2','B3','B4','B5' -replace 'B', 'a'
a1
a2
a3
a4
a5
使用腳本區塊取代
在 PowerShell 6 和更新版本中, -replace 操作員也接受執行取代的腳本區塊。 腳本區塊會針對每個相符項目執行一次。
語法:
<String> -replace <regular-expression>, {<Script-block>}
在腳本區塊內,使用 $_ 自動變數來存取要取代的輸入文字和其他實用資訊。 此變數的類別類型為 System.Text.RegularExpressions.Match。
下列範例會將三位數的每個序列取代為字元對等專案。 腳本區塊會針對需要取代的每個三位數集執行。
'072101108108111' -replace '\d{3}', {return [char][int]$_.Value}
Hello
遏制運算子
內含專案運算子 (-contains、 、 -notcontains-in和 -notin) 類似於等號運算符,不同之處在於它們一律會傳回布爾值,即使輸入是集合也一樣。 這些運算子會在偵測到第一個相符專案時立即停止比較,而相等運算符則會評估所有輸入成員。 在非常大的集合中,這些運算符會傳回比等號運算元更快。
-contains 和 -notcontains
語法:
<Collection> -contains <scalar-object>
<Collection> -notcontains <scalar-object>
這些運算子會告知集合是否包含特定元素。
-contains
當右側 (scalar-object) 符合集合中的其中一個專案時,會傳回 True。
-notcontains 會改為傳回 False。
範例:
'abc', 'def' -contains 'def' # Output: True
'abc', 'def' -notcontains 'def' # Output: False
'Windows', 'PowerShell' -contains 'Shell' # Output: False
'Windows', 'PowerShell' -notcontains 'Shell' # Output: True
'abc', 'def', 'ghi' -contains 'abc', 'def' # Output: False
'abc', 'def', 'ghi' -notcontains 'abc', 'def' # Output: True
更複雜的範例:
$DomainServers = 'ContosoDC1', 'ContosoDC2', 'ContosoFileServer',
'ContosoDNS', 'ContosoDHCP', 'ContosoWSUS'
$thisComputer = 'ContosoDC2'
$DomainServers -contains $thisComputer
# Output: True
當右側操作數是集合時,這些運算符會將值轉換成其字串表示法,然後再將其與左側集合進行比較。
$a = 'abc', 'def'
'abc', 'def', 'ghi' -contains $a # Output: False
# The following statements are equivalent
$a, 'ghi' -contains $a # Output: True
'$a', 'ghi' -contains $a # Output: True
'abc def', 'ghi' -contains $a # Output: True
-in 和 -notin
語法:
<scalar-object> -in <Collection>
<scalar-object> -notin <Collection>
-in和 -notin 運算符是在 PowerShell 3 中引進的,做為 和 -contains 運算子的-notcontains語法反轉。
-in
。
-notin 會改為傳 回 False 。
下列範例會執行與 和範例-contains相同的動作,但會改用 -notcontains 和 -in-notin 來撰寫。
'def' -in 'abc', 'def' # Output: True
'def' -notin 'abc', 'def' # Output: False
'Shell' -in 'Windows', 'PowerShell' # Output: False
'Shell' -notin 'Windows', 'PowerShell' # Output: True
'abc', 'def' -in 'abc', 'def', 'ghi' # Output: False
'abc', 'def' -notin 'abc', 'def', 'ghi' # Output: True
更複雜的範例:
$DomainServers = 'ContosoDC1', 'ContosoDC2', 'ContosoFileServer',
'ContosoDNS', 'ContosoDHCP', 'ContosoWSUS'
$thisComputer = 'ContosoDC2'
$thisComputer -in $DomainServers
# Output: True
當左側操作數是集合時,這些運算符會先將值轉換成其字串表示法,然後再將其與右側集合進行比較。
$a = 'abc', 'def'
$a -in 'abc', 'def', 'ghi' # Output: False
# The following statements are equivalent
$a -in $a, 'ghi' # Output: True
$a -in '$a', 'ghi' # Output: True
$a -in 'abc def', 'ghi' # Output: True
類型比較
型別比較運算子 (-is 和 -isnot) 可用來判斷物件是否為特定類型。
語法:
<object> -is <type-reference>
<object> -isnot <type-reference>
範例:
$a = 1
$b = '1'
$a -is [int] # Output: True
$a -is $b.GetType() # Output: False
$b -isnot [int] # Output: True
$a -isnot $b.GetType() # Output: True