Delen via


about_Switch

Korte beschrijving

Hierin wordt uitgelegd hoe u een switch gebruikt om meerdere voorwaardelijke instructies af te handelen.

Lange beschrijving

Als u een voorwaarde in een script of functie wilt controleren, kunt u een if instructie gebruiken. Met de instructie if kunnen veel soorten voorwaarden worden gecontroleerd, waaronder de waarde van variabelen en de eigenschappen van objecten.

Als u meerdere voorwaarden wilt controleren, kunt u een switch instructie gebruiken. De switch instructie is vergelijkbaar met een reeks if instructies, maar dit is eenvoudiger. De switch instructie bevat elke voorwaarde en de bijbehorende actie. Als een voorwaarde overeenkomt, wordt de actie uitgevoerd.

Belangrijk

Met de switch instructie worden alle waarden geconverteerd naar tekenreeksen voordat deze worden vergeleken.

Syntaxis

Een eenvoudige switch-instructie heeft de volgende indeling:

switch (<test-expression>) {
    <result1-to-be-matched> {<action-statement>}
    <result2-to-be-matched> {<action-statement>}
}

De syntaxis van een switch instructie is vergelijkbaar met de volgende if instructies:

if ("$(<result1-to-be-matched>)") -eq ("$(<test-expression>)") {<action>}
if ("$(<result2-to-be-matched>)") -eq ("$(<test-expression>)") {<action>}

Expressies omvatten letterlijke waarden (tekenreeksen of getallen), variabelen en scriptblokkeringen die een booleaanse waarde retourneren. Met de switch instructie worden alle waarden geconverteerd naar tekenreeksen voordat deze worden vergeleken. Zie voor een voorbeeld impact van tekenreeksconversie verderop in dit artikel.

De <test-expression> waarde wordt geëvalueerd in de expressiemodus. Als de expressie meer dan één waarde retourneert, zoals een matrix of een ander enumereerbaar type, evalueert de switch instructie elke opgesomde waarde afzonderlijk.

Het <result-to-be-matched> is een expressie die moet worden omgezet in één waarde. Deze waarde wordt vergeleken met de invoerwaarde.

De waarde default is gereserveerd voor de actie die wordt gebruikt wanneer er geen andere overeenkomsten zijn.

De instructie switch kan gebruikmaken van de $_ en $switch automatische variabelen. De automatische variabele bevat de waarde van de expressie die is doorgegeven aan de switch instructie en is beschikbaar voor evaluatie en gebruik binnen het bereik van de <result-to-be-matched> instructies. Zie about_Automatic_Variablesvoor meer informatie.

De syntaxis van de volledige switch-instructie is als volgt:

switch [-Regex | -Wildcard | -Exact] [-CaseSensitive] (<test-expression>) {
    string | number | variable | { <value-scriptblock> }
        { <action-statement> }
    default { <action-statement> } # optional
}

of

switch [-Regex | -Wildcard | -Exact] [-CaseSensitive] -File filename {
    string | number | variable | { <value-scriptblock> }
        { <action-statement> }
    default { <action-statement> }  # optional
}

Als u geen parameters gebruikt, gedraagt switch zich hetzelfde als het gebruik van de parameter Exact. Er wordt een niet-hoofdlettergevoelige overeenkomst voor de waarde uitgevoerd. Als de waarde een verzameling is, wordt elk element geëvalueerd in de volgorde waarin het wordt weergegeven.

De switch-instructie moet ten minste één voorwaarde-instructie bevatten.

De default-component wordt geactiveerd wanneer de waarde niet overeenkomt met een van de voorwaarden. Het is gelijk aan een else-component in een if-instructie. Er is slechts één default component toegestaan in elke switch instructie.

switch heeft de volgende parameters:

  • jokerteken - Geeft aan dat de voorwaarde een jokertekenreeks is. Als de overeenkomstcomponent geen tekenreeks is, wordt de parameter genegeerd. De vergelijking is niet hoofdlettergevoelig.
  • Exact - Geeft aan dat de overeenkomstcomponent, als het een tekenreeks is, exact moet overeenkomen. Als de overeenkomstcomponent geen tekenreeks is, wordt deze parameter genegeerd. De vergelijking is niet hoofdlettergevoelig.
  • CaseSensitive - Voert een hoofdlettergevoelige overeenkomst uit. Als de overeenkomstcomponent geen tekenreeks is, wordt deze parameter genegeerd.
  • Bestand - Neemt invoer van een bestand in plaats van een <test-expression>. Het bestand leest een regel tegelijk en wordt geëvalueerd door de instructie switch. De vergelijking is standaard niet hoofdlettergevoelig. De parameter File ondersteunt slechts één bestand. Als er meerdere parameters voor bestand zijn opgenomen, wordt alleen de laatste parameter gebruikt. Zie de voorbeelden van bestandsparameters voor meer informatie.
  • Regex- : voert reguliere expressies uit die overeenkomen met de waarde aan de voorwaarde. Als de overeenkomstcomponent geen tekenreeks is, wordt deze parameter genegeerd. De vergelijking is niet hoofdlettergevoelig. De $Matches automatische variabele is beschikbaar voor gebruik in het overeenkomende instructieblok.

Notitie

Wanneer u conflicterende waarden opgeeft, zoals Regex- en jokerteken, heeft de laatste opgegeven parameter voorrang en worden alle conflicterende parameters genegeerd. Er zijn ook meerdere exemplaren van parameters toegestaan. Alleen de laatst vermelde parameter wordt echter gebruikt.

Voorbeelden

In de volgende voorbeelden ziet u het gebruik van de switch instructie.

Voorbeelden van eenvoudige overeenkomsten

In het volgende voorbeeld vergelijkt de switch-instructie de testwaarde 3 met elk van de voorwaarden. Wanneer de testwaarde overeenkomt met de voorwaarde, wordt de actie uitgevoerd.

switch (3) {
    1 { "It's one."   }
    2 { "It's two."   }
    3 { "It's three." }
    4 { "It's four."  }
}
It's three.

In dit voorbeeld wordt de waarde vergeleken met elke voorwaarde in de lijst. De volgende switch instructie heeft twee voorwaarden voor een waarde van 3, die laat zien dat alle voorwaarden worden getest.

switch (3) {
    1 { "It's one."    }
    2 { "It's two."    }
    3 { "It's three."  }
    4 { "It's four."   }
    3 { "Three again." }
}
It's three.
Three again.

De stroom gebruiken break en continue beheren

Als de waarde overeenkomt met meerdere voorwaarden, wordt de actie voor elke voorwaarde uitgevoerd. Als u dit gedrag wilt wijzigen, gebruikt u de break of continue trefwoorden.

Het break trefwoord stopt met verwerken en sluit de switch-instructie af.

Het continue trefwoord stopt met het verwerken van de huidige waarde, maar blijft eventuele volgende waarden verwerken.

In het volgende voorbeeld wordt een matrix met getallen verwerkt en weergegeven als ze oneven of zelfs zijn. Negatieve getallen worden overgeslagen met het trefwoord continue. Als er een niet-getal wordt aangetroffen, wordt de uitvoering beëindigd met het trefwoord break.

switch (1,4,-1,3,"Hello",2,1) {
    {$_ -lt 0}           { continue }
    {$_ -isnot [int32]}  { break }
    {$_ % 2}             { "$_ is Odd" }
    {-not ($_ % 2)}      { "$_ is Even" }
}
1 is Odd
4 is Even
3 is Odd

Impact van tekenreeksconversie

Alle waarden, zowel invoer als de vergelijkingswaarde, worden geconverteerd naar tekenreeksen voor vergelijking. Als u onbedoelde tekenreeksconversie wilt voorkomen, gebruikt u scriptblokkeringen om de switchwaarde te evalueren.

switch ( ([datetime]'1 Jan 1970').DayOfWeek ) {
    4            { 'The integer value matches a Thursday.' }
    "4"          { 'The numeric string matches a Thursday.' }
    "Thursday"   { 'The string value matches a Thursday.' }
    { 4 -eq $_ } { 'The expression matches a Thursday.' }
}

De eigenschap DayOfWeek van het datumobject is een opsomming. Hoewel opsommingen kunnen worden vergeleken met hun numerieke of tekenreekswaarden, converteert de switch instructie de waarde naar een tekenreeksweergave van de opsomming.

The string value matches a Thursday.
The expression matches a Thursday.

Dit gedrag verschilt van het gedrag van de -eq vergelijking in een if instructie.

if (4 -eq ([datetime]'1 Jan 1970').DayOfWeek) {
    'The integer value matches a Thursday.'
}
The value matches a Thursday.

In dit voorbeeld wordt een hashtabel doorgegeven aan de switch instructie. De switch hashtabel wordt geconverteerd naar een tekenreeks.

$test = @{
    Test  = 'test'
    Test2 = 'test2'
}

$test.ToString()
System.Collections.Hashtable

U ziet dat de tekenreeksweergave van de hashtabel niet hetzelfde is als de waarde van de testsleutel .

switch -Exact ($test) {
    'System.Collections.Hashtable' { 'Hashtable string coercion' }
    'test'                         { 'Hashtable value' }
}
Hashtable string coercion

Gebruiken switch om de waarden in een hashtabel te testen

In dit voorbeeld wordt met de switch instructie getest op het type waarde in de hashtabel. We moeten de items in de hashtabel inventariseren voordat we de waarden kunnen testen. Als u de complicaties van tekenreeksconversie wilt voorkomen, gebruikt u een scriptblok dat een Booleaanse waarde retourneert om de actie-instructie te selecteren die moet worden uitgevoerd.

$var = @{A = 10; B = 'abc'}

foreach ($key in $var.Keys) {
    switch ($var[$key].GetType()) {
        { $_ -eq [int32]  }  { "$key + 10 = $($var[$key] + 10)" }
        { $_ -eq [string] }  { "$key = $($var[$key])"           }
    }
}
A + 10 = 20
B = abc

Jokertekens gebruiken met switch

In dit voorbeeld is er geen overeenkomende case, dus er is geen uitvoer.

switch ("fourteen") {
    1     { "It's one.";   break }
    2     { "It's two.";   break }
    3     { "It's three."; break }
    4     { "It's four.";  break }
    "fo*" { "That's too many."   }
}

Door de default-component toe te voegen, kunt u een actie uitvoeren wanneer er geen andere voorwaarden slagen.

switch ("fourteen") {
    1       { "It's one.";   break }
    2       { "It's two.";   break }
    3       { "It's three."; break }
    4       { "It's four.";  break }
    "fo*"   { "That's too many."   }
    default { "No matches"         }
}
No matches

Als het woord fourteen overeenkomt met een case, moet u de parameter -Wildcard of -Regex gebruiken.

switch -Wildcard ("fourteen") {
    1     { "It's one.";   break }
    2     { "It's two.";   break }
    3     { "It's three."; break }
    4     { "It's four.";  break }
    "fo*" { "That's too many."   }
}
That's too many.

Reguliere expressies gebruiken met switch

In het volgende voorbeeld wordt de parameter -Regex gebruikt.

$target = 'https://bing.com'
switch -Regex ($target) {
    '^ftp\://.*$'
        {
            "$_ is an ftp address"
            break
        }
    '^\w+@\w+\.com|edu|org$'
        {
            "$_ is an email address"
            break
        }
    '^(http[s]?)\://.*$'
        {
            "$_ is a web address that uses $($Matches[1])"
            break
        }
}
https://bing.com is a web address that uses https

In het volgende voorbeeld ziet u het gebruik van scriptblokkeringen als switch instructievoorwaarden.

switch ("Test") {
    { $_ -is [string] } { "Found a string" }
    "Test"              { "This $_ executes as well" }
}
Found a string
This Test executes as well

In het volgende voorbeeld wordt een matrix verwerkt die twee datumwaarden bevat. De <value-scriptblock> vergelijkt de eigenschap Year van elke datum. De <action-statement> geeft een welkomstbericht of het aantal dagen weer tot het begin van het jaar 2022.

switch ((Get-Date 1-Jan-2022), (Get-Date 25-Dec-2021)) {
    { $_.Year -eq 2021 }
        {
            $days = ((Get-Date 1/1/2022) - $_).Days
            "There are $days days until 2022."
        }
    { $_.Year -eq 2022 } { 'Welcome to 2022!' }
}

De inhoud van een bestand lezen met switch

Het gebruik van de switch-instructie met de parameter File is een efficiënte manier om grote bestanden regel per regel te verwerken. PowerShell streamt de regels van het bestand naar de switch-instructie. Elke regel wordt afzonderlijk verwerkt.

U kunt de verwerking beëindigen voordat u het einde van het bestand bereikt met behulp van het trefwoord break in de actie-instructie. De switch-instructie is efficiënter dan het gebruik van Get-Content om grote bestanden per regel te verwerken.

U kunt switch -File combineren met -Wildcard of -Regex voor flexibele en efficiënte line-by-line patroonkoppeling.

In het volgende voorbeeld wordt de README.md in de PowerShell-Docs opslagplaats gelezen. Elke regel wordt uitgevoerd totdat deze de lijn bereikt die begint met ##.

switch -Regex -File .\README.md {
    '^##\s' { break }
    default { $_; continue }
}

Het <filename> argument accepteert expressies met jokertekens, maar moet slechts overeenkomen met één bestand. Het volgende voorbeeld is hetzelfde als de vorige, behalve dat er een jokerteken wordt gebruikt in het argument <filename>. Dit voorbeeld werkt omdat het jokertekenpatroon overeenkomt met slechts één bestand.

switch -Regex -File .\README.* {
    '^##\s' { break }
    default { $_; continue }
}

U moet escapetekens gebruiken die kunnen worden geïnterpreteerd als jokertekens als u wilt dat ze worden behandeld als letterlijke tekens.

$file = (New-Item -Path 'Temp:\Foo[0]' -Value Foo -Force).FullName
switch -File $file { Foo { 'Foo' } }
# No files matching '...\Temp\Foo[0]' were found.

$fileEscaped = [WildcardPattern]::Escape($file)
switch -File $fileEscaped { foo { 'Foo' } }
# Foo

Zie ook