Compartir a través de


about_Switch

Descripción breve

Explica cómo usar un modificador para controlar varias instrucciones condicionales.

Descripción larga

Para comprobar una condición en un script o una función, puede usar una if instrucción . La if instrucción puede comprobar muchos tipos de condiciones, incluido el valor de las variables y las propiedades de los objetos.

Para comprobar varias condiciones, puede usar una switch instrucción . La switch instrucción es similar a una serie de if instrucciones, pero es más sencilla. La switch instrucción enumera cada condición y la acción correspondiente. Si una condición coincide, se realiza la acción.

Importante

La switch instrucción convierte todos los valores en cadenas antes de la comparación.

Sintaxis

Una instrucción básica switch tiene el formato siguiente:

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

La sintaxis de una switch instrucción es similar a las siguientes if instrucciones:

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

Las expresiones incluyen valores literales (cadenas o números), variables y bloques de script que devuelven un valor booleano. La switch instrucción convierte todos los valores en cadenas antes de la comparación. Para obtener un ejemplo, consulte Impacto de la conversión de cadenas más adelante en este artículo.

<test-expression> se evalúa en modo de expresión. Si la expresión devuelve más de un valor, como una matriz u otro tipo enumerable, la switch instrucción evalúa cada valor enumerado por separado.

<result-to-be-matched> es una expresión que debe resolverse en un solo valor. Ese valor se compara con el valor de entrada.

El valor default está reservado para la acción utilizada cuando no hay ninguna otra coincidencia.

La switch instrucción puede usar las $_ variables automáticas y $switch . La variable automática contiene el valor de la expresión que se pasa a la switch instrucción y está disponible para la evaluación y el uso dentro del ámbito de las <result-to-be-matched> instrucciones. Para obtener más información, vea about_Automatic_Variables.

La sintaxis de instrucción completa switch es la siguiente:

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
}

Si no usa parámetros, switch se comporta igual que con el parámetro Exact. Realiza una coincidencia que no distingue mayúsculas de minúsculas para el valor. Si el valor es una colección, cada elemento se evalúa en el orden en que aparece.

La switch instrucción debe incluir al menos una instrucción condition.

La cláusula default se desencadena cuando el valor no coincide con ninguna de las condiciones. Es equivalente a una cláusula else en una instrucción if. Solo se permite una default cláusula en cada switch instrucción.

switch tiene los parámetros siguientes:

  • Comodín : indica que la condición es una cadena comodín. Si la cláusula match no es una cadena, se omite el parámetro . La comparación distingue entre mayúsculas y minúsculas.
  • exacto: indica que la cláusula match, si es una cadena, debe coincidir exactamente. Si la cláusula match no es una cadena, este parámetro se omite. La comparación distingue entre mayúsculas y minúsculas.
  • CaseSensitive : realiza una coincidencia que distingue mayúsculas de minúsculas. Si la cláusula match no es una cadena, este parámetro se omite.
  • archivo: toma la entrada de un archivo en lugar de un <test-expression>. El archivo se lee una línea a la vez y se evalúa mediante la instrucción switch. De forma predeterminada, la comparación no distingue mayúsculas de minúsculas. El parámetro File solo admite un archivo. Si se incluyen varios parámetros File , solo se usa el último. Para obtener más información, vea Ejemplos de parámetros de archivo.
  • Regex : realiza la coincidencia de expresiones regulares del valor con la condición. Si la cláusula match no es una cadena, este parámetro se omite. La comparación distingue entre mayúsculas y minúsculas. La $Matches variable automática está disponible para su uso en el bloque de instrucciones coincidente.

Nota:

Al especificar valores conflictivos, como Regex y Wildcard, el último parámetro especificado tiene prioridad y se omiten todos los parámetros en conflicto. También se permiten varias instancias de parámetros. Sin embargo, solo se usa el último parámetro enumerado.

Ejemplos

En los ejemplos siguientes se muestra el uso de la switch instrucción .

Ejemplos de coincidencias simples

En el ejemplo siguiente, la instrucción switch compara el valor de prueba 3 con cada una de las condiciones. Cuando el valor de prueba coincide con la condición, se realiza la acción.

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

En este ejemplo, el valor se compara con cada condición de la lista. La siguiente instrucción switch tiene dos condiciones para un valor de 3, lo que demuestra que se prueban todas las condiciones.

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.

Uso break y continue para controlar el flujo

Si el valor coincide con varias condiciones, se ejecuta la acción de cada condición. Para cambiar este comportamiento, use las break palabras clave o continue .

La palabra clave detiene el break procesamiento y sale de la switch instrucción .

La continue palabra clave detiene el procesamiento del valor actual, pero continúa procesando los valores posteriores.

En el ejemplo siguiente se procesa una matriz de números y se muestra si son impares o incluso. Los números negativos se omiten con la continue palabra clave . Si se encuentra un no número, la ejecución finaliza con la break palabra clave .

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 de la conversión de cadenas

Todos los valores, tanto input como el valor de comparación se convierten en cadenas para la comparación. Para evitar la conversión de cadenas no deseadas, use bloques de script para evaluar el valor del modificador.

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 propiedad DayOfWeek del objeto date es una enumeración. Aunque las enumeraciones se pueden comparar con sus valores numéricos o de cadena, la switch instrucción convierte el valor en una representación de cadena de la enumeración.

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

Este comportamiento es diferente del comportamiento de la -eq comparación en una if instrucción .

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

En este ejemplo, se pasa una tabla hash a la switch instrucción . switch convierte la tabla hash en una cadena.

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

$test.ToString()
System.Collections.Hashtable

Observe que la representación de cadena de la tabla hash no es la misma que el valor de la clave de prueba .

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

Uso switch para probar los valores de una tabla hash

En este ejemplo, la switch instrucción está probando el tipo del valor en la tabla hash. Debemos enumerar los elementos de la tabla hash para poder probar los valores. Para evitar las complicaciones de la conversión de cadenas, use un bloque de script que devuelva un valor booleano para seleccionar el bloque de script de acción que se va a ejecutar.

$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

Uso de caracteres comodín con switch

En este ejemplo, no hay ningún caso coincidente, por lo que no hay ninguna salida.

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

Al agregar la default cláusula , puede realizar una acción cuando ninguna otra condición se realice correctamente.

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 la palabra fourteen coincida con un caso, debe usar el parámetro -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.

Uso de expresiones regulares con switch

En el ejemplo siguiente se usa el -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

En el ejemplo siguiente se muestra el uso de bloques de script como switch condiciones de instrucción.

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

En el ejemplo siguiente se procesa una matriz que contiene dos valores de fecha. <value-scriptblock> Compara la propiedad Year de cada fecha. <action-scriptblock> muestra un mensaje de bienvenida o el número de días hasta el comienzo del año 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!' }
}

Leer el contenido de un archivo con switch

El uso de la instrucción switch con el parámetro File es una manera eficaz de procesar archivos grandes línea por línea. PowerShell transmite las líneas del archivo a la instrucción switch. Cada línea se procesa individualmente.

Puede finalizar el procesamiento antes de llegar al final del archivo mediante la palabra clave break en la instrucción action. La instrucción switch es más eficaz que usar Get-Content para procesar archivos grandes línea por línea.

Puede combinar switch -File con -Wildcard o -Regex para la coincidencia de patrones de línea a línea flexibles y eficaces.

En el ejemplo siguiente se lee el README.md en el repositorio de PowerShell-Docs. Genera cada línea hasta que llega a la línea que comienza por ##.

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

El <filename> argumento acepta expresiones comodín, pero solo debe coincidir con un archivo. El ejemplo siguiente es el mismo que el anterior, excepto que usa un carácter comodín en el argumento <filename>. Este ejemplo funciona porque el patrón de caracteres comodín coincide solo con un archivo.

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

Debe escapar caracteres que se puedan interpretar como caracteres comodín si desea que se traten como literales.

$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 también