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


about_Comparison_Operators

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

Операторы сравнения в 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[]
0

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

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

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

-eq и -ne

Если левая сторона является скалярной, возвращает значение True, -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 , который реализует System.IEquatable<T> и имеет два свойства: File и Size. Метод 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 собой массив, содержащий элементы NULL:

$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 принимают регулярное выражение (регулярное выражение).

Синтаксис:

<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 поддерживают группы отслеживания регулярных выражений. Каждый раз, когда они выполняются на скалярных входных данных и -match результат имеет значение True или -notmatchFalse, они перезаписывают автоматическую $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_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.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 между двойными кавычками он обозначает переменные и выступает в качестве оператора subexpression.
  • В строке поиска регулярных выражений он обозначает конец строки.
  • В строках подстановки регулярных выражений она обозначает захваченные группы. Не забудьте поместить регулярные выражения между одиночными кавычками или вставить перед ними символ обратного выражения (`).

Пример:

$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> Если оператор to -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 как синтаксический обратный оператор и -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

См. также раздел