次の方法で共有


about_Switch

簡単な説明

スイッチを使用して複数の if ステートメントを処理する方法について説明します。

詳細な説明

スクリプトまたは関数の条件を確認するには、 if ステートメントを使用します。 ifステートメントでは、変数の値やオブジェクトのプロパティなど、さまざまな種類の条件を確認できます。

複数の条件を確認するには、 switch ステートメントを使用します。 switch ステートメントは、一連の if ステートメントと同じですが、より簡単です。 switchステートメントには、各条件とオプションのアクションが一覧表示されます。 条件が取得されると、アクションが実行されます。

switch ステートメントでは、$_$switch自動変数を使用できます。 詳細については、「about_Automatic_Variables」を参照してください。

構文

基本的な switch ステートメントの形式は次のとおりです。

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

同等の if ステートメントは次のとおりです。

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

<test-expression> は、値を返すために式モードで評価される単一の式です。

<result-to-be-matched>は、値が入力値と比較される式です。 式には、ブール値を返すリテラル値 (文字列または数値)、変数、スクリプトブロックが含まれます。

数値として認識されない引用符で囲まれていない値は、文字列として扱われます。 混乱や意図しない文字列変換を回避するには、常に文字列値を引用符で囲む必要があります。 式が正しく評価されるように、式 ()かっこで囲み、部分式を作成します。

<result-to-be-matched> 値が比較式の左側にあることを理解しておくことが重要です。 つまり、 <test-expression> の結果は右側にあり、比較のために左側の値の型に変換できます。 詳細については、 about_Comparison_Operatorsを参照してください。

default値は、他の一致がない場合に使用されるアクション用に予約されています。

$_自動変数には、switch ステートメントに渡される式の値が含まれており、<result-to-be-matched> ステートメントのスコープ内で評価および使用できます。

switchステートメントの完全な構文は次のとおりです。

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

または

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

パラメーターを使用しない場合、switchExact パラメーターの使用と同じように動作します。 値に対して大文字と小文字を区別しない一致が実行されます。 値がコレクションの場合、各要素は表示される順序で評価されます。

switch ステートメントには、少なくとも 1 つの条件ステートメントを含める必要があります。

default 句は、値がいずれの条件にも一致しない場合にトリガーされます。 これは、else ステートメントの if 句と同じです。 各defaultステートメントで許可されるswitch句は 1 つだけです。

switch には、次のパラメーターがあります。

  • ワイルドカード - 条件がワイルドカード文字列であることを示します。 match 句が文字列でない場合、パラメーターは無視されます。 比較では大文字と小文字は区別されません。
  • 正確な - match 句が文字列の場合は、完全に一致する必要があることを示します。 match 句が文字列でない場合、このパラメーターは無視されます。 比較では大文字と小文字は区別されません。
  • CaseSensitive - 大文字と小文字が区別される一致を実行します。 match 句が文字列でない場合、このパラメーターは無視されます。
  • ファイル - <test-expression>ではなく、ファイルから入力を受け取ります。 ファイルは一度に 1 行ずつ読み取られ、switch ステートメントによって評価されます。 既定では、比較では大文字と小文字が区別されません。 File パラメーターは、1 つのファイルのみをサポートします。 複数の File パラメーターが含まれている場合は、最後のパラメーターのみが使用されます。 詳細については、「ファイル パラメーターの例を参照してください。
  • Regex - 値と条件の正規表現の照合を実行します。 match 句が文字列でない場合、このパラメーターは無視されます。 比較では大文字と小文字は区別されません。 $Matches自動変数は、一致するステートメント ブロック内で使用できます。

Note

RegexWildcardなどの競合する値を指定する場合、指定された最後のパラメーターが優先され、競合するすべてのパラメーターは無視されます。 パラメーターの複数のインスタンスも許可されます。 ただし、リストされている最後のパラメーターのみが使用されます。

単純な一致の例

次の例では、switch ステートメントは、テスト値 3 を各条件と比較します。 テスト値が条件と一致すると、アクションが実行されます。

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

この例では、値がリスト内の各条件と比較されます。 次の switch ステートメントには、値 3 の 2 つの条件があり、すべての条件がテストされていることを示します。

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.

一致した後に比較を停止するように switch を指示するには、 break ステートメントを使用します。 break ステートメントは、switch ステートメントを終了します。

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

テスト値が配列などのコレクションの場合は、コレクション内の各項目が表示される順序で評価されます。 次の例では、4 と 2 が評価されます。

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

次の例に示すように、 break ステートメントは、各値ではなくコレクションに適用されます。 switch ステートメントは、値 4 の条件で break ステートメントによって終了します。

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

より複雑な一致の例

この例では、 switch ステートメントはハッシュテーブル内の値の型をテストしています。 実行するスクリプト ブロックを選択するには、ブール値を返す式を使用する必要があります。

$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

この例では、文字列または数値データではないオブジェクトが switchに渡されます。 switchは、オブジェクトに対して文字列強制型変換を実行し、結果を評価します。

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

$test.ToString()

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

この例では、一致するケースがないため、出力はありません。

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句を追加することで、他の条件が成功しなかった場合にアクションを実行できます。

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

単語 fourteen 大文字と小文字を一致させるには、-Wildcard または -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.

次の例では、 -Regex パラメーターを使用します。

$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

次の例では、 switch ステートメント条件としてスクリプト ブロックを使用する方法を示します。

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

次の例では、2 つの日付値を含む配列を処理します。 <value-scriptblock>は、各日付の Year プロパティを比較します。 <action-scriptblock>には、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!' }
}

値が複数の条件と一致する場合は、各条件のアクションが実行されます。 この動作を変更するには、 break キーワードまたは continue キーワードを使用します。

break キーワードは処理を停止し、switch ステートメントを終了します。

continue キーワードは現在の値の処理を停止しますが、後続の値の処理を続行します。

次の例では、数値の配列を処理し、奇数または偶数の場合に表示します。 負の数は、 continue キーワードでスキップされます。 数値以外の値が検出された場合、 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

ファイル パラメーターの例

switch ステートメントを File パラメーターと共に使用すると、大きなファイルを 1 行ずつ効率的に処理できます。 PowerShell は、ファイルの行を switch ステートメントにストリーミングします。 各行は個別に処理されます。

アクション ステートメントで break キーワードを使用して、ファイルの末尾に到達する前に処理を終了できます。 switch ステートメントは、Get-Content を使用して大きなファイルを 1 行ずつ処理するよりも効率的です。

switch -File-Wildcard または -Regex と組み合わせて、柔軟で効率的な行ごとのパターン マッチングを実現できます。

次の例では、PowerShell-Docs リポジトリ内の README.md を読み取ります。 ##で始まる行に達するまで、各行を出力します。

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

<filename> 引数はワイルドカード式として解釈されますが、一致する必要があるファイルは 1 つだけです。 次の例は、<filename> 引数でワイルドカードを使用する点を除き、前の例と同じです。 この例は、ワイルドカード パターンが 1 つのファイルにのみ一致するため機能します。

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

リテラルとして扱う場合は、ワイルドカードとして解釈できる文字をエスケープする必要があります。

$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

関連項目