об операторах сравнения
Краткое описание
Операторы сравнения в 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 как для сравнений с учетом регистра, так и для сравнений без учета регистра. Сравнения выполняются между кодовыми точками Юникода и не используют порядок сортировки, специфичный для языка и региональных параметров. Результаты одинаковы независимо от текущей культуры.
Если левое значение в выражении сравнения является скалярным, оператор возвращает значение Boolean. Если левое значение выражения является коллекцией, оператор возвращает элементы коллекции, соответствующие правому значению выражения. Правые значения всегда рассматриваются как одноэлементные экземпляры, даже если они являются коллекциями. Операторы сравнения не могут эффективно сравнивать коллекции с коллекциями.
Если в коллекции нет совпадений, операторы сравнения возвращают пустой массив. Например:
$a = (1, 2) -eq 3
$a.GetType().Name
$a.Count
Object[]
0
Есть несколько исключений:
- Операторы включения и типа всегда возвращают значение Boolean.
- Оператор
-replace
возвращает результат замены. - Операторы
-match
и-notmatch
также заполняют автоматическую переменную$Matches
, если только левая часть выражения не является коллекцией.
Операторы равенства
-eq
и -ne
Если левая часть скалярная, -eq
возвращает True, если правая часть эквивалентна, в противном случае -eq
возвращает Неверно. -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.IEquatableEquals()
возвращает 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
в левую часть оператора равенства. Размещение его справа не даст того, чего вы ожидаете.
Например, пусть $a
будет массивом, содержащим нулевые элементы:
$a = 1, 2, $null, 4, $null, 6
Следующие тесты проверяют, что $a
не имеет значения NULL.
$null -ne $a
True
Однако следующий пример удаляет все нулевые элементы из $a
:
$a -ne $null # Output: 1, 2, 4, 6
1
2
4
6
-gt
, -ge
, -lt
и -le
-gt
, -ge
, -lt
и -le
ведут себя очень похоже. Когда обе стороны являются скалярными, они возвращают True или False в зависимости от того, как сравниваются две стороны:
-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-клавиатуре нет символа, который сортируется после «а». Он передает набор, содержащий все такие символы, оператору -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
ведут себя аналогично -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, или результатом -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_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
принимает имя пользователя в форме ИмяДомена\ИмяПользователя
и преобразует его в формат ИмяПользователя@ИмяДомена
:
$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
$$
в 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
) аналогичны равенству операторы, за исключением того, что они всегда возвращают значение Boolean, даже если входные данные представляют собой коллекцию. Эти операторы прекращают сравнение, как только обнаруживают первое совпадение, тогда как операторы равенства оценивают все входные элементы. В очень большой коллекции эти операторы возвращают значение быстрее, чем операторы равенства.
-содержит
и -не содержит
Синтаксис:
<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
См. также
- about_Booleans
- about_Operators
- about_Regular_Expressions
- about_Wildcards
- Compare-Object
- Foreach-Object
- Where-Object