about_Comparison_Operators

简短说明

PowerShell 中的比较运算符可以比较两个值或筛选集合元素与输入值。

长说明

使用比较运算符可以比较值或查找与指定模式匹配的值。 PowerShell 包含以下比较运算符:

等式

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

匹配

  • -like, - -ilike-clike 字符串匹配通配符模式
  • -notlike-cnotlike , - -inotlike字符串与通配符模式不匹配
  • -match, - -imatch-cmatch 字符串匹配正则表达式模式
  • -notmatch, - -inotmatch-cnotmatch 字符串与正则表达式模式不匹配

替代功能

  • -replace-creplace-ireplace- 替换匹配正则表达式模式的字符串

Containment

  • -contains-ccontains , - -icontains集合包含值
  • -notcontains-cnotcontains , - -inotcontains集合不包含值
  • -in - 值位于集合中
  • -notin - 值不在集合中

类型

  • -is - 这两个对象的类型相同
  • -isnot - 对象类型不相同

常用功能

除非使用显式区分大小写的运算符,否则字符串比较不区分大小写。 若要使比较运算符区分大小写,请在后面-添加一个 c 。 例如, -ceq 区分大小写的版本 -eq。 若要使不区分大小写,请添加一个 i after -。 例如, -ieq 显式不区分大小写的版本 -eq

运算符的输入为标量值时,运算符返回 布尔 值。 当输入是集合时,运算符返回与表达式右侧值匹配的集合的元素。 如果集合中没有匹配项,比较运算符将返回空数组。 例如:

$a = (1, 2 -eq 3)
$a.GetType().Name
$a.Count
Object[]
0

有几个例外情况:

  • 包含和类型运算符始终返回 布尔
  • 运算符 -replace 返回替换结果
  • -match除非表达式左侧是集合,否则-notmatch运算符还会填充$Matches自动变量。

相等运算符

-eq 和 -ne

当左侧为标量时,如果右侧完全匹配, -eq 则返回 True ,否则 -eq 返回 False-ne 执行相反操作;当双方匹配时返回 False ;否则返回 -neTrue

例如:

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>MyFileInfoSet 类的部分实现,并且具有两个属性:FileSize。 如果Equals()

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 ,具体取决于双方的比较方式:

运算符 返回 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正则表达式 (正则表达式) 。

语法为:

<string[]> -like    <wildcard-expression>
<string[]> -notlike <wildcard-expression>
<string[]> -match    <regular-expression>
<string[]> -notmatch <regular-expression>

当这些运算符的输入是标量值时,它们返回 布尔 值。 当输入是值的集合时,运算符将返回任何匹配的成员。 如果集合中没有匹配项,运算符将返回空数组。

-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 正则表达式捕获组。 每次在标量输入上运行,结果 -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 时,请考虑使用条件语句验证当前运算符调用是否设置了变量。

例如:

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

正则表达式替换

还可以使用正则表达式通过捕获组和替换动态替换文本。 可以在字符串中使用 <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 搜索字符串中,表示行的末尾。
  • 在正则表达式替换字符串中,它表示捕获的组。 请确保在单引号之间放置正则表达式,或在单引号前插入反引号 (`) 字符。

例如:

$1 = 'Goodbye'

'Hello World' -replace '(\w+) \w+', "$1 Universe"
# Output: Goodbye Universe

'Hello World' -replace '(\w+) \w+', '$1 Universe'
# Output: Hello Universe

$$ 在正则表达式中表示文本 $。 这 $$ 在替换字符串中,用于在生成的替换中包含文本 $ 。 例如:

'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) 类似于相等运算符,只是它们始终返回布尔值,即使输入是集合也是如此。 这些运算符在检测到第一个匹配项后立即停止比较,而相等运算符会评估所有输入成员。 在非常大的集合中,这些运算符的返回速度比相等运算符更快。

语法:

<Collection> -contains <Test-object>
<Collection> -notcontains <Test-object>
<Test-object> -in <Collection>
<Test-object> -notin <Collection>

-contains 和 -notcontains

这些运算符指示集是否包含特定元素。 -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
$a, "ghi" -contains $a           # Output: True

-in 和 -notin

PowerShell -in 3 中引入了这些和 -notin 运算符作为语法反 -contains 转和 -notcontains 运算符。 -in当左侧<test-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
$a -in $a, "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

另请参阅