Partilhar via


about_Switch

Breve descrição

Explica como usar uma opção para manipular várias instruções condicionais.

Descrição longa

Para verificar uma condição em um script ou função, você pode usar uma if instrução. A if instrução pode verificar muitos tipos de condições, incluindo o valor de variáveis e as propriedades de objetos.

Para verificar várias condições, você pode usar uma switch instrução. A switch declaração é semelhante a uma série de if declarações, mas é mais simples. A switch instrução lista cada condição e a ação correspondente. Se uma condição corresponder, a ação será executada.

Importante

A switch instrução converte todos os valores em strings antes da comparação.

Sintaxe

Uma instrução básica switch tem o seguinte formato:

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

A sintaxe de uma switch instrução é semelhante às seguintes if instruções:

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

As expressões incluem valores literais (cadeias de caracteres ou números), variáveis e blocos de script que retornam um valor booleano. A switch instrução converte todos os valores em strings antes da comparação. Para obter um exemplo, consulte Impacto da conversão de cadeia de caracteres mais adiante neste artigo.

O <test-expression> é avaliado no modo de expressão. Se a expressão retornar mais de um valor, como uma matriz ou outro tipo enumerável, a switch instrução avaliará cada valor enumerado separadamente.

O <result-to-be-matched> é uma expressão deve resolver para um único valor. Esse valor é comparado com o valor de entrada.

O valor default é reservado para a ação usada quando não há outras correspondências.

A switch instrução pode usar as $_ variáveis e $switch automáticas. A variável automática contém o valor da expressão passada para a switch instrução e está disponível para avaliação e uso dentro do escopo das <result-to-be-matched> instruções. Para obter mais informações, consulte about_Automatic_Variables.

A sintaxe completa switch da instrução é a seguinte:

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

ou

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

Se você não usar parâmetros, switch se comportará da mesma forma que usar o parâmetro Exact. Ele executa uma correspondência que não diferencia maiúsculas de minúsculas para o valor. Se o valor for uma coleção, cada elemento será avaliado na ordem em que aparece.

A switch declaração deve incluir pelo menos uma declaração de condição.

A cláusula default é acionada quando o valor não corresponde a nenhuma das condições. É equivalente a uma cláusula else em uma declaração if. Apenas uma default cláusula é permitida em cada switch declaração.

switch tem os seguintes parâmetros:

  • Curinga - Indica que a condição é uma cadeia de caracteres curinga. Se a cláusula de correspondência não for uma cadeia de caracteres, o parâmetro será ignorado. A comparação não diferencia maiúsculas de minúsculas.
  • exata - Indica que a cláusula de correspondência, se for uma cadeia de caracteres, deve corresponder exatamente. Se a cláusula de correspondência não for uma cadeia de caracteres, esse parâmetro será ignorado. A comparação não diferencia maiúsculas de minúsculas.
  • CaseSensitive - Executa uma correspondência que diferencia maiúsculas de minúsculas . Se a cláusula de correspondência não for uma cadeia de caracteres, esse parâmetro será ignorado.
  • File - Recebe entrada de um arquivo em vez de um <test-expression>. O arquivo é lido uma linha de cada vez e avaliado pela instrução switch. Por padrão, a comparação não diferencia maiúsculas de minúsculas. O parâmetro File suporta apenas um arquivo. Se vários parâmetros de arquivo forem incluídos, apenas o último será usado. Para obter mais informações, consulte os exemplos de parâmetros File.
  • Regex - Executa a correspondência de expressão regular do valor com a condição. Se a cláusula de correspondência não for uma cadeia de caracteres, esse parâmetro será ignorado. A comparação não diferencia maiúsculas de minúsculas. A $Matches variável automática está disponível para uso dentro do bloco de instrução correspondente.

Nota

Ao especificar valores conflitantes, como Regex e Wildcard, o último parâmetro especificado tem precedência e todos os parâmetros conflitantes são ignorados. Várias instâncias de parâmetros também são permitidas. No entanto, apenas o último parâmetro listado é usado.

Exemplos

Os exemplos a seguir demonstram o uso da switch instrução.

Exemplos de correspondência simples

No exemplo a seguir, a instrução switch compara o valor de teste 3 a cada uma das condições. Quando o valor do teste corresponde à condição, a ação é executada.

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

Neste exemplo, o valor é comparado a cada condição na lista. A instrução switch a seguir tem duas condições para um valor de 3, o que demonstra que todas as condições são testadas.

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.

Utilizar break e continue controlar o fluxo

Se o valor corresponder a várias condições, a ação para cada condição será executada. Para alterar esse comportamento, use as break palavras-chave ou continue .

A break palavra-chave para de processar e sai da switch instrução.

A continue palavra-chave para de processar o valor atual, mas continua processando quaisquer valores subsequentes.

O exemplo a seguir processa uma matriz de números e exibe se eles são ímpares ou pares. Os números negativos são ignorados com a continue palavra-chave. Se um não-número for encontrado, a execução será encerrada com a break palavra-chave.

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

Impacto da conversão de cadeia de caracteres

Todos os valores, tanto a entrada quanto o valor de comparação, são convertidos em cadeias de caracteres para comparação. Para evitar a conversão não intencional de cadeia de caracteres, use blocos de script para avaliar o valor do switch.

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

A propriedade DayOfWeek do objeto date é uma enumeração. Embora as enumerações possam ser comparadas com seus valores numéricos ou de cadeia de caracteres, a switch instrução converte o valor em uma representação de cadeia de caracteres da enumeração.

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

Esse comportamento é diferente do comportamento da -eq comparação em uma if declaração.

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

Neste exemplo, uma hashtable é passada para a switch instrução. O switch converte a hashtable em uma cadeia de caracteres.

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

$test.ToString()
System.Collections.Hashtable

Observe que a representação de cadeia de caracteres da hashtable não é a mesma que o valor da chave Test .

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

Use switch para testar os valores em uma hashtable

Neste exemplo, a switch instrução está testando o tipo do valor na hashtable. Devemos enumerar os itens na hashtable antes de podermos testar os valores. Para evitar as complicações da conversão de cadeia de caracteres, use um bloco de script que retorna um valor booleano para selecionar o bloco de script de ação a ser executado.

$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

Use curingas com switch

Neste exemplo, não há nenhum caso correspondente, portanto, não há saída.

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

Ao adicionar a default cláusula, você pode executar uma ação quando nenhuma outra condição for bem-sucedida.

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

Para que a palavra fourteen corresponda a um caso, você deve usar o parâmetro -Wildcard ou -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.

Use expressões regulares com switch

O exemplo a seguir usa o -Regex parâmetro.

$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

O exemplo a seguir demonstra o uso de blocos de script como switch condições de instrução.

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

O exemplo a seguir processa uma matriz que contém dois valores de data. O <value-scriptblock> compara a propriedade Year de cada data. O <action-scriptblock> exibe uma mensagem de boas-vindas ou o número de dias até o início do ano de 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!' }
}

Leia o conteúdo de um ficheiro com switch

Usar a instrução switch com o parâmetro File é uma maneira eficiente de processar arquivos grandes linha por linha. O PowerShell transmite as linhas do arquivo para a instrução switch. Cada linha é processada individualmente.

Você pode encerrar o processamento antes de chegar ao final do arquivo usando a palavra-chave break na instrução action. A instrução switch é mais eficiente do que usar Get-Content para processar arquivos grandes linha por linha.

Você pode combinar switch -File com -Wildcard ou -Regex para uma correspondência de padrões flexível e eficiente linha a linha.

O exemplo a seguir lê o README.md no repositório PowerShell-Docs. Ele produz cada linha até chegar à linha que começa com ##.

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

O <filename> argumento aceita expressões curinga, mas deve corresponder a apenas um arquivo. O exemplo a seguir é o mesmo que o anterior, exceto que usa um curinga no argumento <filename>. Este exemplo funciona porque o padrão curinga corresponde a apenas um arquivo.

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

Você deve escapar de caracteres que podem ser interpretados como curingas se quiser que eles sejam tratados como literais.

$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

Consulte também