about_Comparison_Operators

Krótki opis

Operatory porównania w programie PowerShell mogą porównywać dwie wartości lub filtrować elementy kolekcji względem wartości wejściowej.

Długi opis

Operatory porównania umożliwiają porównywanie wartości lub znajdowanie wartości pasujących do określonych wzorców. Program PowerShell zawiera następujące operatory porównania:

Równości

  • -eq, , -ieq-ceq — równa się
  • -ne, -ine, -cne — nie równa się
  • -gt, -igt-cgt — większe niż
  • -ge, -ige-cge — większe niż lub równe
  • -lt, -ilt-clt — mniejsze niż
  • -le, -ile-cle — mniejsze niż lub równe

Dopasowania

  • -like, -ilike-clike — ciąg pasuje do wzorca symboli wieloznacznych
  • -notlike, -cnotlike-inotlikeciąg nie jest zgodny ze wzorcem symboli wieloznacznych
  • -match, -imatch-cmatch — ciąg pasuje do wzorca wyrażenia regularnego
  • -notmatch, -cnotmatch , -inotmatch— ciąg nie jest zgodny ze wzorcem wyrażenia regularnego

części sprzętowych

  • -replace, -ireplace-creplace — zastępuje ciągi pasujące do wzorca wyrażenia regularnego

Zamknięcia

  • -contains-ccontains , , -icontains— kolekcja zawiera wartość
  • -notcontains, -inotcontains-cnotcontains — kolekcja nie zawiera wartości
  • -in - wartość znajduje się w kolekcji
  • -notin — wartość nie znajduje się w kolekcji

Type

  • -is - oba obiekty są tego samego typu
  • -isnot - obiekty nie są tego samego typu

Typowe funkcje

Porównania ciągów są niewrażliwe na wielkość liter, chyba że używasz jawnego operatora z uwzględnieniem wielkości liter. Aby podać wielkość liter operatora porównania, dodaj element c po .- Na przykład -ceq jest uwzględniana wielkość liter w -eqwersji . Aby jawnie nie uwzględniać wielkości liter, dodaj element i po -. Na przykład -ieq jest jawnie bez uwzględniania wielkości liter w wersji -eq.

Porównania ciągów używają zmiennej InvariantCulture zarówno w przypadku porównań z uwzględnieniem wielkości liter, jak i bez uwzględniania wielkości liter. Porównania są między punktami kodu Unicode i nie używają kolejności sortowania specyficznego dla kultury. Wyniki są takie same niezależnie od bieżącej kultury.

Gdy dane wejściowe operatora są wartością skalarną, operator zwraca wartość logiczną. Gdy dane wejściowe są kolekcją, operator zwraca elementy kolekcji zgodne z prawą wartością wyrażenia. Jeśli w kolekcji nie ma dopasowań, operatory porównania zwracają pustą tablicę. Na przykład:

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

Istnieje kilka wyjątków:

  • Operatory zawierania i typów zawsze zwracają wartość logiczną
  • Operator -replace zwraca wynik zastępczy
  • Operatory -match i -notmatch wypełniają również zmienną $Matches automatyczną, chyba że lewa strona wyrażenia jest kolekcją.

Operatory równości

-eq i -ne

Gdy lewa strona jest skalarna, zwraca wartość True, jeśli prawa strona jest równoważna, w przeciwnym razie -eq zwraca wartość False. -eq -ne wykonuje odwrotnie; zwraca wartość False , gdy obie strony są równoważne; w przeciwnym razie -ne zwraca wartość True.

Przykład:

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

Gdy lewa strona jest kolekcją, -eq zwraca te elementy członkowskie, które pasują do prawej strony, a następnie -ne filtruje je.

Przykład:

1,2,3 -eq 2             # Output: 2
"abc", "def" -eq "abc"  # Output: abc
"abc", "def" -ne "abc"  # Output: def

Te operatory przetwarzają wszystkie elementy kolekcji. Przykład:

"zzz", "def", "zzz" -eq "zzz"
zzz
zzz

Operator równości może porównywać obiekty różnych typów. Ważne jest, aby zrozumieć, że wartość po prawej stronie porównania można przekonwertować na typ wartości po lewej stronie do porównania.

Na przykład ciąg '1.0' jest konwertowany na liczbę całkowitą, która ma być porównywana z wartością 1. Ten przykład zwraca wartość True.

PS> 1 -eq '1.0'
True

W tym przykładzie wartość 1 jest konwertowana na ciąg, który ma być porównywany z ciągiem '1.0'. Ten przykład zwraca wartość False.

PS> '1.0' -eq 1
False

Operatory równości akceptują wszystkie dwa obiekty, a nie tylko skalarne lub kolekcje. Jednak wynik porównania nie jest gwarantowany dla użytkownika końcowego. W poniższym przykładzie pokazano problem.

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

W tym przykładzie utworzyliśmy dwa obiekty o identycznych właściwościach. Jednak wynik testu równości ma wartość False , ponieważ są to różne obiekty. Aby utworzyć porównywalne klasy, należy zaimplementować klasę System.IEquatable<T> w swojej klasie. W poniższym przykładzie pokazano częściową implementację klasy MyFileInfoSet, która implementuje metodę System.IEquatable<T> i ma dwie właściwości: Plik i Rozmiar. Metoda Equals() zwraca wartość True , jeśli właściwości File (Plik) i Size (Rozmiar) dwóch obiektów MyFileInfoSet są takie same.

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

Wybitnym przykładem porównywania dowolnych obiektów jest stwierdzenie, czy mają wartość null. Jeśli jednak musisz określić, czy zmienna to $null, należy umieścić $null po lewej stronie operatora równości. Umieszczenie go po prawej stronie nie robi tego, czego oczekujesz.

Na przykład niech $a będzie tablicą zawierającą elementy o wartości null:

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

Następujące testy, które $a nie mają wartości null.

$null -ne $a
True

Następujące elementy zgłaszają jednak wszystkie elementy o wartości null z elementu $a:

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

-gt, -ge, -lt i -le

-gt, , -ge-lti -le zachowuje się bardzo podobnie. Gdy obie strony są skalarne, zwracają wartość Prawda lub Fałsz w zależności od tego, jak obie strony porównują:

Operator Zwraca wartość True, gdy...
-gt Lewa strona jest większa
-ge Lewa strona jest większa lub równa
-lt Lewa strona jest mniejsza
-le Lewa strona jest mniejsza lub równa

W poniższych przykładach wszystkie instrukcje zwracają wartość True.

8 -gt 6  # Output: True
8 -ge 8  # Output: True
6 -lt 8  # Output: True
8 -le 8  # Output: True

Uwaga

W większości języków programowania operator większy niż .> W programie PowerShell ten znak jest używany do przekierowywania. Aby uzyskać szczegółowe informacje, zobacz about_Redirection.

Gdy lewa strona jest kolekcją, te operatory porównują każdy element członkowski kolekcji z prawej strony. W zależności od ich logiki zachowują lub odrzucają element członkowski.

Przykład:

$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

Te operatory współpracują z dowolną klasą, która implementuje element System.IComparable.

Przykłady:

# 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'

W poniższym przykładzie pokazano, że nie ma symbolu na amerykańskiej klawiaturze QWERTY, która jest sortowana po znaku "a". Przekazuje zestaw zawierający wszystkie takie symbole operatorowi -gt , aby porównać je z "a". Dane wyjściowe są pustą tablicą.

$a=' ','`','~','!','@','#','$','%','^','&','*','(',')','_','+','-','=',
   '{','}','[',']',':',';','"','''','\','|','/','?','.','>',',','<'
$a -gt 'a'
# Output: Nothing

Jeśli obie strony operatorów nie są rozsądnie porównywalne, te operatory zgłaszają błąd niepowodujący zakończenia.

Pasujące operatory

Pasujące operatory (-like, -notlike, -matchi -notmatch) znajdują elementy zgodne lub nie pasują do określonego wzorca. Wzorzec dla -like elementu i -notlike jest wyrażeniem wieloznacznymi (zawierającym *, ?i [ ]), podczas gdy -match i -notmatch akceptuje wyrażenie regularne (Regex).

Składnia jest następująca:

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

Gdy dane wejściowe tych operatorów są wartością skalarną, zwracają wartość logiczną .

Gdy dane wejściowe są kolekcją wartości, każdy element w kolekcji jest konwertowany na ciąg do porównania. Operatory -match i -notmatch zwracają odpowiednio wszystkie pasujące i niezgodne elementy członkowskie. Operatory -like i -notlike zwracają jednak elementy członkowskie jako ciągi. Ciąg zwracany dla elementu członkowskiego kolekcji -like przez i -notlike jest ciągiem, który jest operatorem używanym do porównania i jest uzyskiwany przez rzutowanie elementu członkowskiego do ciągu.

-like i -notlike

-likei zachowują się podobnie do -eq i -ne-notlike , ale po prawej stronie może być ciąg zawierający symbole wieloznaczne.

Przykład:

"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 i -notmatch

-match i -notmatch użyj wyrażeń regularnych, aby wyszukać wzorzec w wartościach po lewej stronie. Wyrażenia regularne mogą być zgodne ze złożonymi wzorcami, takimi jak adresy e-mail, ścieżki UNC lub sformatowane numery telefonów. Ciąg po prawej stronie musi być zgodny z regułami wyrażeń regularnych .

Przykłady skalarne:

# 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

Jeśli dane wejściowe są kolekcją, operatorzy zwracają pasujące elementy członkowskie tej kolekcji.

Przykłady kolekcji:

"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 obsługa -notmatch grup przechwytywania wyrażeń regularnych. Za każdym razem, gdy są uruchamiane na danych wejściowych skalarnych, a -match wynik ma wartość True lub -notmatch wynik ma wartość False, zastępują zmienną automatyczną $Matches . $Matchesjest tabelą skrótu, która zawsze ma klucz o nazwie "0", który przechowuje całe dopasowanie. Jeśli wyrażenie regularne zawiera grupy przechwytywania, $Matches zawiera dodatkowe klucze dla każdej grupy.

Należy pamiętać, że tabela skrótów $Matches zawiera tylko pierwsze wystąpienie dowolnego pasującego wzorca.

Przykład:

$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 Jeśli wynik ma wartość Fałsz lub -notmatch wynik ma wartość True lub gdy dane wejściowe są kolekcją, $Matches zmienna automatyczna nie jest zastępowana. W związku z tym będzie zawierać wcześniej ustawioną wartość lub $null jeśli zmienna nie została ustawiona. Podczas odwoływania się po wywołaniu jednego z tych operatorów rozważ sprawdzenie, czy zmienna została ustawiona przez wywołanie $Matches bieżącego operatora przy użyciu instrukcji warunku.

Przykład:

if ("<version>1.0.0</version>" -match '<version>(.*?)</version>') {
    $Matches
}

Aby uzyskać szczegółowe informacje, zobacz about_Regular_Expressions i about_Automatic_Variables.

Operator zastępczy

Zastępowanie za pomocą wyrażeń regularnych

Podobnie jak -match, -replace operator używa wyrażeń regularnych do znalezienia określonego wzorca. Jednak w przeciwieństwie do -matchmetody zastępuje dopasowania inną określoną wartością.

Składnia:

<input> -replace <regular-expression>, <substitute>

Operator zastępuje całą lub część wartości określoną wartością przy użyciu wyrażeń regularnych. Możesz użyć operatora dla wielu zadań administracyjnych, takich jak zmiana nazwy plików. Na przykład następujące polecenie zmienia rozszerzenia nazw plików wszystkich .txt plików na .log:

Get-ChildItem *.txt | Rename-Item -NewName { $_.name -replace '\.txt$','.log' }

Domyślnie -replace operator nie uwzględnia wielkości liter. Aby uwzględniać wielkość liter, użyj polecenia -creplace. Aby jawnie nie uwzględniać wielkości liter, użyj polecenia -ireplace.

Przykłady:

"book" -ireplace "B", "C" # Case insensitive
"book" -creplace "B", "C" # Case-sensitive; hence, nothing to replace
Cook
book

Począwszy od programu PowerShell 7.2, gdy operand po lewej stronie w -replace instrukcji operatora nie jest ciągiem, operand jest konwertowany na ciąg. Program PowerShell wykonuje konwersję ciągów bez uwzględniania kultury.

Jeśli na przykład twoja kultura jest ustawiona na francuski (fr), uwzględniana w kulturze konwersja ciągu wartości 1.2 to 1,2.

Przed programem PowerShell 7.2:

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

W programie PowerShell 7.2 lub nowszym:

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

Podstawienia wyrażeń regularnych

Można również używać wyrażeń regularnych do dynamicznego zastępowania tekstu przy użyciu przechwytywania grup i podstawień. Do grup przechwytywania można odwoływać się w <substitute> ciągu przy użyciu znaku dolara ($) przed identyfikatorem grupy.

W poniższym przykładzie -replace operator akceptuje nazwę użytkownika w postaci DomainName\Username i konwertuje na Username@DomainName format:

$SearchExp = '^(?<DomainName>[\w-.]+)\\(?<Username>[\w-.]+)$'
$ReplaceExp = '${Username}@${DomainName}'

'Contoso.local\John.Doe' -replace $SearchExp, $ReplaceExp
John.Doe@Contoso.local

Ostrzeżenie

Znak $ ma role składniowe zarówno w programie PowerShell, jak i wyrażeniach regularnych:

  • W programie PowerShell między podwójnym cudzysłowem wyznacza zmienne i działa jako operator podexpressionu.
  • W ciągach wyszukiwania wyrażeń regularnych oznacza koniec wiersza.
  • W ciągach podstawienia wyrażenia regularnego oznacza przechwycone grupy. Pamiętaj, aby umieścić wyrażenia regularne między pojedynczymi cudzysłowami lub wstawić znak backtick (`) przed nimi.

Na przykład:

$1 = 'Goodbye'

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

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

$$ w regex oznacza literał $. To $$ w ciągu podstawienia, aby uwzględnić literał $ w wynikowym zastąpieniu. Na przykład:

'5.72' -replace '(.+)', '$ $1' # Output: $ 5.72
'5.72' -replace '(.+)', '$$$1' # Output: $5.72
'5.72' -replace '(.+)', '$$1'  # Output: $1

Aby dowiedzieć się więcej, zobacz about_Regular_Expressions i podstawienia w wyrażeniach regularnych.

Podstawianie w kolekcji

<input> Gdy operator to -replace kolekcja, program PowerShell stosuje zamianę do każdej wartości w kolekcji. Na przykład:

"B1","B2","B3","B4","B5" -replace "B", 'a'
a1
a2
a3
a4
a5

Zastępowanie blokiem skryptu

W programie PowerShell 6 lub nowszym -replace operator akceptuje również blok skryptu, który wykonuje zamianę. Blok skryptu jest uruchamiany raz dla każdego dopasowania.

Składnia:

<String> -replace <regular-expression>, {<Script-block>}

W bloku skryptu użyj zmiennej automatycznej $_ , aby uzyskać dostęp do zastępowanego tekstu wejściowego i innych przydatnych informacji. Typ klasy tej zmiennej to System.Text.RegularExpressions.Match.

Poniższy przykład zastępuje każdą sekwencję trzech cyfr odpowiednikami znaków. Blok skryptu jest uruchamiany dla każdego zestawu trzech cyfr, które należy zamienić.

"072101108108111" -replace "\d{3}", {return [char][int]$_.Value}
Hello

Operatory zawierania

Operatory zawierania (-contains, -notcontains, -ini -notin) są podobne do operatorów równości, z tą różnicą, że zawsze zwracają wartość logiczną , nawet jeśli dane wejściowe są kolekcją. Te operatory przestają porównywać natychmiast po wykryciu pierwszego dopasowania, podczas gdy operatory równości oceniają wszystkie składowe danych wejściowych. W bardzo dużej kolekcji te operatory są zwracane szybciej niż operatory równości.

-contains i -notcontains

Składnia:

<Collection> -contains <scalar-object>
<Collection> -notcontains <scalar-object>

Te operatory informują, czy zestaw zawiera określony element. -contains Zwraca wartość True , gdy po prawej stronie (obiekt skalarny) pasuje do jednego z elementów w zestawie. -notcontains Metoda zwraca wartość False.

Przykłady:

"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

Bardziej złożone przykłady:

$DomainServers = "ContosoDC1","ContosoDC2","ContosoFileServer","ContosoDNS",
                 "ContosoDHCP","ContosoWSUS"
$thisComputer  = "ContosoDC2"

$DomainServers -contains $thisComputer
# Output: True

Gdy operand po prawej stronie jest kolekcją, te operatory konwertują wartość na reprezentację ciągu przed porównaniem jej z kolekcją po lewej stronie.

$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 i -notin

Składnia:

<scalar-object> -in <Collection>
<scalar-object> -notin <Collection>

Operatory -in i -notin zostały wprowadzone w programie PowerShell 3 jako składniowy zwrot operatorów -contains i -notcontains . -in Zwraca wartość True , gdy lewa strona <scalar-object> pasuje do jednego z elementów w kolekcji. -notin Metoda zwraca wartość False .

W poniższych przykładach są takie same, jak przykłady -contains i -notcontains nie, ale zamiast tego są napisane za pomocą -in polecenia i -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

Bardziej złożone przykłady:

$DomainServers = "ContosoDC1","ContosoDC2","ContosoFileServer","ContosoDNS",
                 "ContosoDHCP","ContosoWSUS"
$thisComputer  = "ContosoDC2"

$thisComputer -in $DomainServers
# Output: True

Gdy operand po lewej stronie jest kolekcją, te operatory konwertują wartość na reprezentację ciągu przed porównaniem jej z kolekcją po prawej stronie.

$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

Porównanie typów

Operatory porównania typów (-is i -isnot) służą do określania, czy obiekt jest określonym typem.

Składnia:

<object> -is <type-reference>
<object> -isnot <type-reference>

Przykład:

$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

Zobacz też