Sdílet prostřednictvím


o přepínači

Krátký popis

Vysvětluje, jak pomocí přepínače zpracovat více podmíněných příkazů.

Dlouhý popis

Pokud chcete zkontrolovat podmínku ve skriptu nebo funkci, můžete použít příkaz if . Příkaz if může kontrolovat mnoho typů podmínek, včetně hodnoty proměnných a vlastností objektů.

Pokud chcete zkontrolovat více podmínek, můžete použít switch příkaz. Příkaz switch je podobný řadě if příkazů, ale je jednodušší. Příkaz switch uvádí každou podmínku a odpovídající akci. Pokud se podmínka shoduje, provede se akce.

Důležité

Příkaz switch před porovnáním převede všechny hodnoty na řetězce.

Syntaxe

Základní switch příkaz má následující formát:

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

Syntaxe switch příkazu je podobná následujícím if příkazům:

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

Výrazy zahrnují hodnoty literálů (řetězce nebo čísla), proměnné a bloky skriptu, které vracejí logickou hodnotu. Příkaz switch před porovnáním převede všechny hodnoty na řetězce. Příklad najdete v části Dopad převodu řetězců dále v tomto článku.

Vyhodnotí se <test-expression> v režimu výrazu. Pokud výraz vrátí více než jednu hodnotu, například matici nebo jiný výčtový typ, switch příkaz vyhodnotí každou výčtovou hodnotu zvlášť.

Jedná se <result-to-be-matched> o výraz, který se musí přeložit na jednu hodnotu. Tato hodnota se porovná se vstupní hodnotou.

Hodnota default je vyhrazena pro akci použitou v případě, že neexistují žádné jiné shody.

Příkaz switch může používat $_ proměnné a $switch automatické proměnné. Automatická proměnná obsahuje hodnotu výrazu předaného příkazu switch a je k dispozici pro vyhodnocení a použití v rámci rozsahu <result-to-be-matched> příkazů. Další informace najdete v tématu about_Automatic_Variables.

Úplná switch syntaxe příkazu je následující:

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

nebo

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

Pokud nepoužíváte parametry, switch se chová stejně jako použití parametru Exact. Pro hodnotu se provádí shoda nerozlišující malá a velká písmena. Pokud je hodnota kolekce, každý prvek se vyhodnotí v pořadí, ve kterém se zobrazí.

Příkaz switch musí obsahovat alespoň jeden příkaz podmínky.

Klauzule default se aktivuje, když hodnota neodpovídá žádné z podmínek. Je ekvivalentní klauzuli else v příkazu if. V každém default příkazu je povolená pouze jedna switch klauzule.

switch má následující parametry:

  • Zástupný znak – označuje, že podmínka je řetězec se zástupným znakem. Pokud klauzule match není řetězec, parametr se ignoruje. Porovnání nerozlišuje malá a velká písmena.
  • Přesná – označuje, že klauzule shody, pokud se jedná o řetězec, musí přesně odpovídat. Pokud klauzule match není řetězec, bude tento parametr ignorován. Porovnání nerozlišuje malá a velká písmena.
  • Malá a velká písmena – provede shodu s rozlišováním velkých a malých písmen. Pokud klauzule match není řetězec, bude tento parametr ignorován.
  • soubor – přebírá vstup ze souboru místo <test-expression>. Soubor načte řádek najednou a vyhodnotí se příkazem switch. Ve výchozím nastavení porovnání nerozlišuje malá a velká písmena. Parametr File podporuje pouze jeden soubor. Pokud je součástí více parametrů souboru , použije se pouze poslední. Další informace najdete v příkladech parametrů File.
  • Regulární výraz – provede porovnávání regulárního výrazu hodnoty s podmínkou. Pokud klauzule match není řetězec, bude tento parametr ignorován. Porovnání nerozlišuje malá a velká písmena. Automatická $Matches proměnná je k dispozici pro použití v rámci odpovídajícího bloku příkazu.

Poznámka:

Při zadávání konfliktních hodnot, jako je Regex a Wildcard, má poslední zadaný parametr přednost a všechny konfliktní parametry jsou ignorovány. Je také povoleno více instancí parametrů. Použije se ale pouze poslední uvedený parametr.

Examples

Následující příklady ukazují použití switch příkazu.

Jednoduché příklady shody

V následujícím příkladu příkaz switch porovnává testovací hodnotu 3 s každou z podmínek. Když testovací hodnota odpovídá podmínce, provede se akce.

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

V tomto příkladu se hodnota porovná s každou podmínkou v seznamu. Následující příkaz switch má dvě podmínky pro hodnotu 3, která ukazuje, že jsou testovány všechny podmínky.

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.

Použití break a continue řízení toku

Pokud hodnota odpovídá více podmínkám, provede se akce pro každou podmínku. Chcete-li toto chování změnit, použijte break klíčová slova.continue

Klíčové break slovo zastaví zpracování a ukončí switch příkaz.

Klíčové continue slovo přestane zpracovávat aktuální hodnotu, ale nadále zpracovává všechny následné hodnoty.

Následující příklad zpracuje matici čísel a zobrazí, jestli jsou liché nebo sudé. Záporná čísla se přeskočí klíčovým slovem continue . Pokud dojde k nečíslu, spuštění se ukončí pomocí klíčového break slova.

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

Dopad převodu řetězců

Všechny hodnoty, vstupní i porovnávací hodnota jsou převedeny na řetězce pro porovnání. Chcete-li zabránit neúmyslnému převodu řetězců, použijte bloky skriptu k vyhodnocení hodnoty přepínače.

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.' }
}

DayOfWeek Vlastnost objektu date je výčet. I když lze výčty porovnat s jejich číselnými nebo řetězcovými hodnotami, switch příkaz převede hodnotu na řetězcovou reprezentaci výčtu.

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

Toto chování se liší od chování -eq porovnání v if příkazu.

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

V tomto příkladu switch se do příkazu předá zatřiďovací tabulka. Převede switch hashovatelnou tabulku na řetězec.

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

$test.ToString()
System.Collections.Hashtable

Všimněte si, že řetězcová reprezentace hashtable není stejná jako hodnota testovacího klíče.

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

Slouží switch k otestování hodnot v hashovatelné tabulce.

V tomto příkladu switch příkaz testuje typ hodnoty v hashtable. Než hodnoty otestujeme, musíme vytvořit výčet položek v hashovatelné tabulce. Chcete-li se vyhnout komplikacím převodu řetězců, použijte blok skriptu, který vrátí logickou hodnotu k výběru bloku skriptu akce ke spuštění.

$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

Použití zástupných znaků s switch

V tomto příkladu neexistuje žádný odpovídající případ, takže neexistuje žádný výstup.

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 Přidáním klauzule můžete provést akci, pokud žádné jiné podmínky nebudou úspěšné.

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

Aby se slovo fourteen shodovaly s případem, musíte použít parametr -Wildcard nebo -Regex.

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.

Použití regulárních výrazů s switch

Následující příklad používá -Regex parametr.

$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

Následující příklad ukazuje použití bloků skriptu jako switch podmínky příkazu.

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

Následující příklad zpracuje pole obsahující dvě hodnoty kalendářních dat. Porovná <value-scriptblock> vlastnost Year každého data. Zobrazí <action-scriptblock> uvítací zprávu nebo počet dní do začátku roku 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!' }
}

Čtení obsahu souboru pomocí switch

Použití příkazu switch s parametrem File představuje efektivní způsob zpracování velkých souborů po řádku. PowerShell streamuje řádky souboru do příkazu switch. Každý řádek se zpracovává jednotlivě.

Zpracování můžete ukončit před dosažením konce souboru pomocí klíčového slova break v příkazu akce. Příkaz switch je efektivnější než použití Get-Content ke zpracování velkých souborů po řádku.

switch -File můžete kombinovat s -Wildcard nebo -Regex pro flexibilní a efektivní porovnávání vzorů po řádech.

Následující příklad přečte README.md v úložišti PowerShell-Docs. Vypíše každý řádek, dokud nedosáhne řádku, který začíná ##.

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

Argument <filename> přijímá výrazy se zástupnými znaky, ale musí odpovídat pouze jednomu souboru. Následující příklad je stejný jako předchozí s tím rozdílem, že používá zástupný znak v argumentu <filename>. Tento příklad funguje, protože vzor zástupných znaků odpovídá pouze jednomu souboru.

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

Pokud chcete, aby se s nimi zacházelo jako s literály, musíte řídicí znaky, které lze interpretovat jako zástupné znaky.

$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

Viz také