共用方式為


about_Comparison_Operators

簡短描述

PowerShell 中的比較運算符可以比較兩個值或篩選集合元素與輸入值。

完整描述

比較運算子可讓您比較值或尋找符合指定模式的值。 PowerShell 包含下列比較運算子:

平等

  • -eq-ieq-ceq 、 - 等於
  • -ne-ine-cne 、 - 不等於
  • -gt-igt-cgt 、 - 大於
  • -ge-ige-cge 、 - 大於或等於
  • -lt-ilt-clt 、 - 小於
  • -le-ile-cle 、 - 小於或等於

Matching

  • -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 - 值位於集合中
  • -notin - 值不在集合中

類型

  • -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 傳回 True

範例:

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.IEquatable<T> 且具有兩個屬性 File SizeMyFileInfoSet 類別部分實作。 如果兩個 MyFileInfoSet 物件的 File 和 Size 屬性相同,此方法Equals()會傳回 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 的行為非常類似。 當兩端都是純量時,會根據兩端的比較方式傳回 TrueFalse

運算子 當...
-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模式是包含 、 ?[ ]) 的通配符表示式 (*,而 接受-notmatch-match正則表示式 (Regex -notlike) 。

語法是:

<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

-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 擷取群組。 每次在純量輸入上執行,結果 -matchTrue,或 -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結果為 True,或輸入為集合時,$Matches不會覆寫自動變數。 因此,它將會包含先前設定的值,如果變數尚未設定,則 $null 為 。 在叫用其中一個運算符之後參考 $Matches 時,請考慮使用 condition 語句來確認目前運算符調用已設定變數。

範例:

if ("<version>1.0.0</version>" -match '<version>(.*?)</version>') {
    $Matches
}

如需詳細資訊,請參閱 about_Regular_Expressionsabout_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 開始,當 operator 語句中的 -replace 左側操作數不是字串時,該操作數就會轉換成字串。 PowerShell 會執行不區分文化特性的字串轉換。

例如,如果您的文化特性設定為法文 (fr) ,則值的 1.2 區分文化特性字串轉換為 1,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 當右側 (純量物件) 符合集合中的其中一個專案時,會傳回 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 中引進,作為和 -notcontains 運算子的-contains語法反轉。 -in當左側<scalar-object>符合集合中的其中一個專案時,會傳回 True-notin 會改為傳回 False

下列範例會執行 與範例相同的動作-contains,但會改用 -in-notcontains-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

另請參閱