相关文章推荐
谦逊的红豆  ·  Orillusion荣获SegmentFau ...·  2 月前    · 
无聊的汉堡包  ·  Problem with ...·  12 月前    · 
微笑的松球  ·  javascript - How to ...·  1 年前    · 
失落的勺子  ·  自定义滚动条样式 --- ...·  1 年前    · 

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 字符串匹配正则表达式模式
  • -notmatch -inotmatch - -cnotmatch 字符串与正则表达式模式不匹配
  • -replace -ireplace -creplace - 替换与正则表达式模式匹配的字符串
  • -contains -icontains - -ccontains 集合包含值
  • -notcontains -inotcontains - -cnotcontains 集合不包含值
  • -in - 值在集合中
  • -notin - 值不在集合中
  • -is - 这两个对象是同一类型
  • -isnot - 对象不是同一类型
  • 除非使用区分大小写的显式运算符,否则字符串比较不区分大小写。 若要使比较运算符区分大小写,请在 - 后面添加 c 。 例如, -ceq 是 区分大小写的版本 -eq 。 若要显式区分大小写,请在 后面 - 添加 i 。 例如, -ieq 是 显式不区分大小写的版本 -eq

    字符串比较使用 InvariantCulture 进行区分大小写和不区分大小写的比较。

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

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

    有几个例外情况:

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

    -eq 和 -ne

    当左侧为标量时,如果右侧等效, -eq 则返回 True ;否则返回 -eqFalse-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"
    

    相等运算符可以比较不同类型的对象。 请务必了解,该值位于比较的右侧,可以转换为左侧值的类型进行比较。

    例如,字符串 '1.0' 转换为整数,以便与值 1进行比较。 此示例返回 True

    PS> 1 -eq '1.0'
    

    在此示例中,值 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> 。 以下示例演示 了 MyFileInfoSet 类的部分实现,该类实现 System.IEquatable<T> 并具有两个属性 :FileSize。 如果两个 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
    

    比较任意对象的一个突出示例是找出它们是否为 null。 但是,如果需要确定变量是否为 $null,则必须放在 $null 相等运算符的左侧。 将其放在右侧不会按预期操作。

    例如,让我们 $a 是一个包含 null 元素的数组:

    $a = 1, 2, $null, 4, $null, 6
    

    以下测试 $a 不为 null。

    $null -ne $a
    

    但是,以下文件从 中取出所有 null 元素 $a

    $a -ne $null # Output: 1, 2, 4, 6
    

    -gt、-ge、-lt 和 -le

    -gt-ge-lt-le 的行为非常相似。 当两端均为标量时,它们将返回 TrueFalse ,具体取决于双方的比较方式:

    在大多数编程语言中,大于 运算符为 >。 在 PowerShell 中,此字符用于重定向。 有关详细信息,请参阅 about_Redirection

    当左侧是集合时,这些运算符会将集合的每个成员与右侧进行比较。 根据逻辑,他们保留或放弃成员。

    $a=5, 6, 7, 8, 9
    Write-Output "Test collection:"
    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:
    Members greater than 7
    Members greater than or equal to 7
    Members smaller than 7
    Members smaller than or equal to 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) 查找与指定模式匹配或不匹配的元素。 和 -notlike-like模式是一个通配符表达式, (包含 *?[ ]) ,而 -match-notmatch 接受正则表达式 (正则表达式) 。

    <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 支持正则表达式捕获组。 每次它们在标量输入上运行,结果 -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
    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
    

    从 PowerShell 7.2 开始,当运算符语句中的 -replace 左侧操作数不是字符串时,该操作数将转换为字符串。 PowerShell 执行不区分区域性的字符串转换。

    例如,如果区域性设置为法语 (fr) ,则值的 1.2 区域性敏感字符串转换为 1,2

    PowerShell 7.2 之前:

    PS> [cultureinfo]::CurrentCulture = 'fr'
    PS> 1.2 -replace ','
    

    在 PowerShell 7.2 及更高版本中:

    PS> [cultureinfo]::CurrentCulture = 'fr'
    PS> 1.2 -replace ','
    

    正则表达式替换

    还可以使用正则表达式通过捕获组和替换来动态替换文本。 可以在字符串中使用 <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 中,在双引号之间,它指定变量并充当子表达式运算符。
  • 在正则表达式搜索字符串中,它表示行的末尾。
  • 在正则表达式替换字符串中,它表示捕获的组。 请确保将正则表达式放在单引号之间,或在正则表达式前面插入反引号 (`) 个字符。
  • $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>当 to 运算符-replace是集合时,PowerShell 会将 替换应用于集合中的每个值。 例如:

    "B1","B2","B3","B4","B5" -replace "B", 'a'
    

    替换为脚本块

    在 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

    -in-notin 运算符在 PowerShell 3 中作为 和 -notcontains 运算符的-contains语法反向引入。 -in当左侧<test-object>匹配集中的元素之一时,返回 True-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
    $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
    
  • about_Booleans
  • about_Operators
  • about_Regular_Expressions
  • about_Wildcards
  • Compare-Object
  • Foreach-Object
  • Where-Object
  •