Поделиться через


о_операторах_сравнения

Краткое описание

Операторы сравнения в 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 находит и заменяет строки, соответствующие шаблону регулярных выражений.

Сдерживание

  • -contains, — -icontains-ccontains коллекция содержит значение
  • -notcontains, — -inotcontains-cnotcontains коллекция не содержит значения
  • -in, -iin, -cin — значение находится в коллекции
  • -notin, -inotin, -cnotin — значение не в коллекции

Тип

  • -is — оба объекта являются одинаковыми типами
  • -isnot — объекты не совпадают с типом

Общие функции

Сравнение строк не учитывает регистр, если не используется явный оператор регистра. Чтобы сделать оператор сравнения регистром, добавьте c после -. Например, это версия с -ceq учетом регистра -eq. Чтобы сделать регистр нечувствительной явной, добавьте после i-. Например, -ieq является явно нечувствительной версией регистра -eq.

Сравнения строк используют invariantCulture для сравнения без учета регистра и регистра. Сравнения между точками кода юникода и не используют порядок сортировки, зависящих от языка и региональных параметров. Результаты одинаковы независимо от текущего языка и региональных параметров.

Если левое значение в выражении сравнения является скалярным значением, оператор возвращает логическое значение. Если левое значение в выражении является коллекцией, оператор возвращает элементы коллекции, соответствующие правому значению выражения. Значения справа всегда рассматриваются как одноэлементные экземпляры, даже если они являются коллекциями. Операторы сравнения не могут эффективно сравнивать коллекции с коллекциями.

Если в коллекции нет совпадений, операторы сравнения возвращают пустой массив. Например:

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

Существует несколько исключений:

  • Операторы хранения и типа всегда возвращают логическое значение.
  • Оператор -replace возвращает результат замены
  • -match Операторы -notmatch также заполняют $Matches автоматическую переменную, если левая часть выражения не является коллекцией.

Операторы равенства

-eq и -ne

Если левая сторона скалярна, возвращает -eq, если правая сторона эквивалентна, в противном случае -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> в классе. В следующем примере показана частичная реализация класса MyFileInfoSet, реализующего , и имеет два свойства, < и >. Метод Equals() возвращает значение True , если свойства File и Size двух объектов MyFileInfoSet одинаковы.

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 массив, содержащий пустые элементы:

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

Следующие тесты, не $a допускающие значения NULL.

$null -ne $a
True

Однако следующие файлы из всех элементов NULL $aиз:

$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 передает выражение подстановочного знака синтаксическому анализатору. Чтобы сопоставить один из подстановочных знаков (*или?[ ]), необходимо экранировать его с помощью символа backtick (`). Например, чтобы сопоставить литерал ?, используйте `? в выражении подстановочного знака. Если вы используете расширяемое строковое выражение 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 поддержка групп отслеживания регулярных выражений. Каждый раз, когда они выполняются на скалярных входных данных, и -match результат имеет значение True-notmatch, они перезаписывают автоматическую переменную. $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 после вызова одного из этих операторов рекомендуется убедиться, что переменная была задана вызовом текущего оператора с помощью инструкции условия.

Пример:

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 выполняет преобразование строки без учета языка и региональных параметров.

Например, если язык и региональные параметры заданы для французского 1.2 языка (fr), преобразование строки с учетом языка и региональных параметров равно 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 он обозначает захваченные группы. Не забудьте поместить регулярные выражения между одними кавычками или вставить перед ними символ backtick (`).

Например:

$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) похожи на операторы равенства, за исключением того, что они всегда возвращают логическое значение, даже если входные данные являются коллекцией. Эти операторы перестают сравнивать, как только они обнаруживают первое совпадение, а операторы равенства оценивают все входные элементы. В очень большой коллекции эти операторы возвращаются быстрее, чем операторы равенства.

-содержит и -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 в качестве синтаксического обратного -contains элемента и -notcontains операторов. -in Возвращает значение True , если левая сторона <scalar-object> соответствует одному из элементов коллекции. -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

См. также