Condividi tramite


informazioni su Switch

Breve descrizione

Viene illustrato come usare un'opzione per gestire più istruzioni condizionali.

Descrizione lunga

Per controllare una condizione in uno script o una funzione, è possibile usare un'istruzione if . L'istruzione if può controllare molti tipi di condizioni, tra cui il valore delle variabili e le proprietà degli oggetti.

Per controllare più condizioni, è possibile usare un'istruzione switch . L'istruzione switch è simile a una serie di if istruzioni, ma è più semplice. L'istruzione switch elenca ogni condizione e l'azione corrispondente. Se una condizione corrisponde, viene eseguita l'azione.

Importante

L'istruzione converte tutti i valori in stringhe prima del switch confronto.

Sintassi

Un'istruzione di base switch ha il formato seguente:

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

La sintassi di un'istruzione switch è simile alle istruzioni seguenti if :

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

Le espressioni includono valori letterali (stringhe o numeri), variabili e scriptblock che restituiscono un valore booleano. L'istruzione converte tutti i valori in stringhe prima del switch confronto. Per un esempio, vedere Impatto della conversione di stringhe più avanti in questo articolo.

L'oggetto <test-expression> viene valutato in modalità espressione. Se l'espressione restituisce più di un valore, ad esempio una matrice o un altro tipo enumerabile, l'istruzione switch valuta ogni valore enumerato separatamente.

<result-to-be-matched> è un'espressione che deve essere risolta in un singolo valore. Tale valore viene confrontato con il valore di input.

Il valore default è riservato per l'azione utilizzata quando non sono presenti altre corrispondenze.

L'istruzione switch può usare le $_ variabili automatiche e $switch . La variabile automatica contiene il valore dell'espressione passata all'istruzione ed è disponibile per la switch valutazione e l'uso nell'ambito delle <result-to-be-matched> istruzioni. Per altre informazioni, vedere about_Automatic_Variables.

La sintassi completa switch dell'istruzione è la seguente:

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

o

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

Se non si usano parametri, switch si comporta allo stesso modo dell'uso del parametro Exact. Esegue una corrispondenza senza distinzione tra maiuscole e minuscole per il valore. Se il valore è una raccolta, ogni elemento viene valutato nell'ordine in cui viene visualizzato.

L'istruzione switch deve includere almeno un'istruzione condition.

La clausola default viene attivata quando il valore non corrisponde ad alcuna delle condizioni. Equivale a una clausola else in un'istruzione if. In ogni default istruzione è consentita una switch sola clausola.

switch ha i parametri seguenti:

  • Carattere jolly: indica che la condizione è una stringa con caratteri jolly. Se la clausola match non è una stringa, il parametro viene ignorato. Il confronto non fa distinzione tra maiuscole e minuscole.
  • esatto : indica che la clausola di corrispondenza, se si tratta di una stringa, deve corrispondere esattamente. Se la clausola match non è una stringa, questo parametro viene ignorato. Il confronto non fa distinzione tra maiuscole e minuscole.
  • CaseSensitive : esegue una corrispondenza con distinzione tra maiuscole e minuscole. Se la clausola match non è una stringa, questo parametro viene ignorato.
  • File: accetta input da un file anziché da un <test-expression>. Il file viene letto una riga alla volta e valutata dall'istruzione switch. Per impostazione predefinita, il confronto non fa distinzione tra maiuscole e minuscole. Il parametro file supporta un solo file. Se sono inclusi più parametri file , viene usato solo l'ultimo parametro. Per altre informazioni, vedere esempi di parametri file.
  • Regex : esegue la corrispondenza dell'espressione regolare del valore alla condizione. Se la clausola match non è una stringa, questo parametro viene ignorato. Il confronto non fa distinzione tra maiuscole e minuscole. La $Matches variabile automatica è disponibile per l'uso all'interno del blocco di istruzioni corrispondente.

Nota

Quando si specificano valori in conflitto, ad esempio Regex e Wildcard, l'ultimo parametro specificato ha la precedenza e tutti i parametri in conflitto vengono ignorati. Sono consentite anche più istanze di parametri. Tuttavia, viene usato solo l'ultimo parametro elencato.

Esempi

Negli esempi seguenti viene illustrato l'uso dell'istruzione switch .

Esempi di corrispondenze semplici

Nell'esempio seguente, l'istruzione switch confronta il valore del test 3 con ognuna delle condizioni. Quando il valore del test corrisponde alla condizione, viene eseguita l'azione.

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

In questo esempio, il valore viene confrontato con ogni condizione nell'elenco. L'istruzione switch seguente presenta due condizioni per un valore pari a 3, che dimostra che vengono testate tutte le condizioni.

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.

Usare break e continue per controllare il flusso

Se il valore corrisponde a più condizioni, viene eseguita l'azione per ogni condizione. Per modificare questo comportamento, usare le break parole chiave o continue .

La break parola chiave interrompe l'elaborazione ed esce dall'istruzione switch .

La continue parola chiave interrompe l'elaborazione del valore corrente, ma continua l'elaborazione dei valori successivi.

L'esempio seguente elabora una matrice di numeri e visualizza se sono dispari o pari. I numeri negativi vengono ignorati con la continue parola chiave . Se viene rilevato un numero diverso da un numero, l'esecuzione viene terminata con la break parola chiave .

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

Impatto della conversione di stringhe

Tutti i valori, sia di input che di confronto, vengono convertiti in stringhe per il confronto. Per evitare la conversione imprevista di stringhe, usare blocchi di script per valutare il valore dell'opzione.

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

La proprietà DayOfWeek dell'oggetto date è un'enumerazione . Mentre le enumerazioni possono essere confrontate con i valori numerici o stringa, l'istruzione switch converte il valore in una rappresentazione di stringa dell'enumerazione.

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

Questo comportamento è diverso dal comportamento del -eq confronto in un'istruzione if .

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

In questo esempio viene passata una tabella hash all'istruzione switch . switch Converte la tabella hash in una stringa.

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

$test.ToString()
System.Collections.Hashtable

Si noti che la rappresentazione di stringa della tabella hash non corrisponde al valore della chiave di test .

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

Usare switch per testare i valori in una tabella hash

In questo esempio l'istruzione esegue il switch test per il tipo del valore nella tabella hash. È necessario enumerare gli elementi nella tabella hash prima di poter testare i valori. Per evitare le complicazioni della conversione di stringhe, usare un blocco di script che restituisce un valore booleano per selezionare lo script di azione da eseguire.

$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

Usare caratteri jolly con switch

In questo esempio non esiste alcuna distinzione tra maiuscole e minuscole, quindi non è presente alcun output.

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

Aggiungendo la default clausola , è possibile eseguire un'azione quando nessuna altra condizione ha esito positivo.

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

Affinché la parola fourteen corrisponda a un caso, è necessario usare il parametro -Wildcard o -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.

Usare espressioni regolari con switch

Nell'esempio seguente viene usato il -Regex parametro .

$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

Nell'esempio seguente viene illustrato l'uso di blocchi di script come switch condizioni di istruzione.

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

Nell'esempio seguente viene elaborata una matrice contenente due valori di data. Confronta <value-scriptblock> la proprietà Year di ogni data. <action-scriptblock> Visualizza un messaggio di benvenuto o il numero di giorni fino all'inizio dell'anno 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!' }
}

Leggere il contenuto di un file con switch

L'uso dell'istruzione switch con il parametro file è un modo efficiente per elaborare file di grandi dimensioni riga per riga. PowerShell trasmette le righe del file all'istruzione switch. Ogni riga viene elaborata singolarmente.

È possibile terminare l'elaborazione prima di raggiungere la fine del file usando la parola chiave break nell'istruzione action. L'istruzione switch è più efficiente rispetto all'uso di Get-Content per elaborare file di grandi dimensioni riga per riga.

È possibile combinare switch -File con -Wildcard o -Regex per criteri line-by-line flessibili ed efficienti.

Nell'esempio seguente viene letto il README.md nel repository PowerShell-Docs. Restituisce ogni riga fino a raggiungere la riga che inizia con ##.

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

L'argomento <filename> accetta espressioni con caratteri jolly, ma deve corrispondere a un solo file. L'esempio seguente è uguale a quello precedente, ad eccezione del fatto che usa un carattere jolly nell'argomento <filename>. Questo esempio funziona perché il criterio con caratteri jolly corrisponde a un solo file.

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

È necessario usare caratteri di escape che possono essere interpretati come caratteri jolly se si desidera che vengano considerati come valori letterali.

$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

Vedere anche