about_Comparison_Operators

Kort beskrivning

Jämförelseoperatorerna i PowerShell kan antingen jämföra två värden eller filtrera element i en samling mot ett indatavärde.

Lång beskrivning

Med jämförelseoperatorer kan du jämföra värden eller hitta värden som matchar angivna mönster. PowerShell innehåller följande jämförelseoperatorer:

Likhet

  • -eq, -ieq, -ceq - är lika med
  • -ne, -ine, -cne - är inte lika med
  • -gt, -igt, -cgt - större än
  • -ge, -ige, -cge - större än eller lika med
  • -lt, -ilt, -clt - mindre än
  • -le, -ile, -cle - mindre än eller lika med

Matching

  • -like, -ilike, -clike – strängen matchar jokerteckenmönstret
  • -notlike, -inotlike, -cnotlike – strängen matchar inte jokerteckenmönstret
  • -match, -imatch, -cmatch – strängen matchar regex-mönstret
  • -notmatch, -inotmatch, -cnotmatch – strängen matchar inte regex-mönstret

Ny funktion

  • -replace, -ireplace, -creplace – ersätter strängar som matchar ett regex-mönster

Behållare

  • -contains, -icontains, -ccontains – samlingen innehåller ett värde
  • -notcontains, -inotcontains, -cnotcontains – samlingen innehåller inget värde
  • -in - värdet finns i en samling
  • -notin - värdet finns inte i en samling

Typ

  • -is – båda objekten har samma typ
  • -isnot - objekten är inte av samma typ

Vanliga funktioner

Strängjämförelser är skiftlägesokänsliga om du inte använder den explicita skiftlägeskänsliga operatorn. Om du vill göra en jämförelseoperator skiftlägeskänslig lägger du till en c efter -. Är till exempel -ceq den skiftlägeskänsliga versionen av -eq. Om du vill göra skiftlägeskänslighet explicit lägger du till efter i-. Är till exempel -ieq den uttryckligen skiftlägesokänsliga versionen av -eq.

När indata för en operator är ett skalärt värde returnerar operatorn ett booleskt värde. När indata är en samling returnerar operatorn elementen i samlingen som matchar uttryckets högra värde. Om det inte finns några matchningar i samlingen returnerar jämförelseoperatorerna en tom matris. Exempel:

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

Det finns några undantag:

  • Operatorerna containment och type returnerar alltid ett booleskt värde
  • Operatorn -replace returnerar ersättningsresultatet
  • Operatorerna -match och -notmatch fyller även i den $Matches automatiska variabeln om inte uttryckets vänstra sida är en samling.

Likhetsoperatorer

-eq och -ne

När den vänstra sidan är skalär -eq returneras Sant om den högra sidan är en exakt matchning, annars -eq returneras False. -ne gör motsatsen. den returnerar False när båda sidor matchar; annars -ne returneras True.

Exempel:

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

När den vänstra sidan är en samling -eq returnerar de medlemmar som matchar den högra sidan, samtidigt -ne som de filtreras bort.

Exempel:

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

Dessa operatorer bearbetar alla element i samlingen. Exempel:

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

Likhetsoperatorn kan jämföra objekt av olika typer. Det är viktigt att förstå att värdet finns till höger om jämförelsen kan konverteras till typen av det vänstra värdet för jämförelse.

Strängen '1.0' konverteras till exempel till ett heltal som ska jämföras med värdet 1. Det här exemplet returnerar True.

PS> 1 -eq '1.0'
True

I det här exemplet konverteras värdet 1 till en sträng som ska jämföras med strängen '1.0'. Det här exemplet returnerar False.

PS> '1.0' -eq 1
False

Likhetsoperatorerna accepterar två objekt, inte bara en skalär eller samling. Men jämförelseresultatet är inte garanterat meningsfullt för slutanvändaren. I följande exempel visas problemet.

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

I det här exemplet skapade vi två objekt med identiska egenskaper. Ändå är likhetstestresultatet Falskt eftersom de är olika objekt. Om du vill skapa jämförbara klasser måste du implementera System.IEquatable<T> i klassen. I följande exempel visas den partiella implementeringen av en MyFileInfoSet-klass som implementerar System.IEquatable<T> och har två egenskaper: Fil och storlek. Metoden Equals() returnerar True om egenskaperna File och Size för två MyFileInfoSet-objekt är desamma.

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

Ett framträdande exempel på att jämföra godtyckliga objekt är att ta reda på om de är null. Men om du behöver avgöra om en variabel är $nullmåste du placera $null på vänster sida av likhetsoperatorn. Att lägga det på höger sida gör inte vad du förväntar dig.

Låt oss $a till exempel vara en matris som innehåller null-element:

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

Följande tester är $a inte null.

$null -ne $a
True

Följande filers dock ut alla null-element från $a:

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

-gt, -ge, -lt och -le

-gt, -ge, -ltoch -le beter sig på liknande sätt. När båda sidor är skalär returnerar de Sant eller Falskt beroende på hur de två sidorna jämför:

Operator Returnerar Sant när...
-gt Den vänstra sidan är större
-ge Den vänstra sidan är större eller lika med
-lt Den vänstra sidan är mindre
-le Den vänstra sidan är mindre eller lika med

I följande exempel returnerar alla instruktioner True.

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

Anteckning

I de flesta programmeringsspråk är >operatorn större än . I PowerShell används det här tecknet för omdirigering. Mer information finns i about_Redirection.

När den vänstra sidan är en samling jämför dessa operatorer varje medlem i samlingen med höger sida. Beroende på deras logik behåller eller tar de bort medlemmen.

Exempel:

$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

Dessa operatorer fungerar med alla klasser som implementerar System.IComparable.

Exempel:

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

Följande exempel visar att det inte finns någon symbol på ett amerikanskt QWERTY-tangentbord som sorteras efter "a". Den matar en uppsättning som innehåller alla sådana symboler till operatorn -gt för att jämföra dem med "a". Utdata är en tom matris.

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

Om de två sidorna av operatörerna inte är någorlunda jämförbara utlöser dessa operatörer ett icke-avslutande fel.

Matchande operatorer

Matchande operatorer (-like, -notlike, -matchoch -notmatch) hittar element som matchar eller inte matchar ett angivet mönster. Mönstret för -like och är ett uttryck med jokertecken (som innehåller *, ?och [ ]), medan -match och -notmatch accepterar ett reguljärt uttryck (Regex-notlike).

Syntax:

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

När indata för dessa operatorer är ett skalärt värde returnerar de ett booleskt värde. När indata är en samling värden returnerar operatorerna alla matchande medlemmar. Om det inte finns några matchningar i en samling returnerar operatorerna en tom matris.

-like och -notlike

-like och -notlike fungerar på liknande sätt som -eq och -ne, men den högra sidan kan vara en sträng som innehåller jokertecken.

Exempel:

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

-match och -notmatch använd reguljära uttryck för att söka efter mönster i värdena på vänster sida. Reguljära uttryck kan matcha komplexa mönster som e-postadresser, UNC-sökvägar eller formaterade telefonnummer. Strängen på höger sida måste följa reglerna för reguljära uttryck .

Skalära exempel:

# 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

Om indata är en samling returnerar operatorerna matchande medlemmar i samlingen.

Samlingsexempel:

"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 och -notmatch stöder regex capture-grupper. Varje gång de körs på skalära indata och -match resultatet är Sant, eller -notmatch om resultatet är Falskt, skriver de över den $Matches automatiska variabeln. $Matches är en hash-tabell som alltid har en nyckel med namnet "0", som lagrar hela matchningen. Om det reguljära uttrycket innehåller insamlingsgrupper $Matches innehåller det ytterligare nycklar för varje grupp.

Observera att hashtabellen $Matches endast innehåller den första förekomsten av matchande mönster.

Exempel:

$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

När resultatet -match är Falskt, eller om -notmatch resultatet är Sant, eller när indata är en samling, skrivs inte den $Matches automatiska variabeln över. Därför innehåller den det tidigare angivna värdet, eller $null om variabeln inte har angetts. När du refererar efter att ha anropat $Matches en av dessa operatorer bör du kontrollera att variabeln har angetts av det aktuella operatoranropet med hjälp av en villkorsinstrukation.

Exempel:

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

Mer information finns i about_Regular_Expressions och about_Automatic_Variables.

Ersättningsoperator

Ersättning med reguljära uttryck

Precis som -matchanvänder operatorn -replace reguljära uttryck för att hitta det angivna mönstret. Men till skillnad från -matchersätter den matchningarna med ett annat angivet värde.

Syntax:

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

Operatorn ersätter hela eller delar av ett värde med det angivna värdet med hjälp av reguljära uttryck. Du kan använda operatorn för många administrativa uppgifter, till exempel byta namn på filer. Följande kommando ändrar till exempel filnamnstilläggen för alla .txt filer till .log:

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

Som standard är operatorn -replace skiftlägesokänslig. Om du vill göra det skiftlägeskänsligt använder du -creplace. Om du vill göra det explicit skiftlägeskänsligt använder du -ireplace.

Exempel:

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

Ersättningar för reguljära uttryck

Det är också möjligt att använda reguljära uttryck för att dynamiskt ersätta text med hjälp av insamlingsgrupper och ersättningar. Avbildningsgrupper kan refereras till i strängen <substitute> med hjälp av dollartecknet ($) före gruppidentifieraren.

I följande exempel accepterar operatorn -replace ett användarnamn i formatet DomainName\Username och konverterar till Username@DomainName formatet:

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

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

Varning

Tecknet $ har syntatiska roller i både PowerShell och reguljära uttryck:

  • I PowerShell, mellan dubbla citattecken, anger den variabler och fungerar som en underuttrycksoperator.
  • I Regex-söksträngar anger den slutet av raden.
  • I Regex-ersättningssträngar anger den insamlade grupper. Se till att antingen placera dina reguljära uttryck mellan enkla citattecken eller infoga ett backtick-tecken (`) före dem.

Exempel:

$1 = 'Goodbye'

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

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

$$ i Regex anger en literal $. Detta $$ i ersättningssträngen för att inkludera en literal $ i den resulterande ersättningen. Exempel:

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

Mer information finns i about_Regular_Expressions och ersättningar i reguljära uttryck.

Ersätta i en samling

<input> När till-operatorn -replace är en samling tillämpar PowerShell ersättningen på varje värde i samlingen. Exempel:

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

Ersätta med ett skriptblock

I PowerShell 6 och senare accepterar operatören -replace också ett skriptblock som utför ersättningen. Skriptblocket körs en gång för varje matchning.

Syntax:

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

I skriptblocket använder du den $_ automatiska variabeln för att komma åt den indatatext som ersätts och annan användbar information. Den här variabelns klasstyp är System.Text.RegularExpressions.Match.

I följande exempel ersätts varje sekvens med tre siffror med teckenmotsvarigheterna. Skriptblocket körs för varje uppsättning med tre siffror som måste ersättas.

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

Inneslutningsoperatorer

Inneslutningsoperatorerna (-contains, -notcontains, -inoch -notin) liknar likhetsoperatorerna, förutom att de alltid returnerar ett booleskt värde, även när indata är en samling. Dessa operatorer slutar jämföra så fort de identifierar den första matchningen, medan likhetsoperatorerna utvärderar alla indatamedlemmar. I en mycket stor samling returnerar dessa operatorer snabbare än likhetsoperatorerna.

Syntax:

<Collection> -contains <Test-object>
<Collection> -notcontains <Test-object>
<Test-object> -in <Collection>
<Test-object> -notin <Collection>

-contains och -notcontains

Dessa operatorer anger om en uppsättning innehåller ett visst element. -contains returnerar Sant när den högra sidan (testobjektet) matchar ett av elementen i uppsättningen. -notcontains returnerar False i stället. När testobjektet är en samling använder dessa operatorer referensjämlikhet, d.v.s. de kontrollerar om ett av uppsättningens element är samma instans av testobjektet.

Exempel:

"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

Mer komplexa exempel:

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

Operatorerna -in och -notin introducerades i PowerShell 3 som syntaktisk omvänd av operatorerna -contains och -notcontains . -in returnerar Sant när den vänstra sidan <test-object> matchar ett av elementen i uppsättningen. -notin returnerar False i stället. När testobjektet är en uppsättning använder dessa operatorer referensjämlikhet för att kontrollera om ett av uppsättningens element är samma instans av testobjektet.

Följande exempel gör samma sak som exemplen för -contains och -notcontains gör, men de skrivs med -in och -notin i stället.

"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

Mer komplexa exempel:

$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

Typjämförelse

Typjämförelseoperatorerna (-is och -isnot) används för att avgöra om ett objekt är en viss typ.

Syntax:

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

Exempel:

$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

Se även