簡単な説明
スイッチを使用して複数の条件付きステートメントを処理する方法について説明します。
詳細な説明
スクリプトまたは関数の条件を確認するには、 if
ステートメントを使用します。
if
ステートメントでは、変数の値やオブジェクトのプロパティなど、さまざまな種類の条件を確認できます。
複数の条件を確認するには、 switch
ステートメントを使用します。
switch
ステートメントは、一連のif
ステートメントに似ていますが、より簡単です。
switch
ステートメントには、各条件と対応するアクションが一覧表示されます。 条件が一致すると、アクションが実行されます。
Von Bedeutung
switch
ステートメントは、比較前にすべての値を文字列に変換します。
構文
基本的な switch
ステートメントの形式は次のとおりです。
switch (<test-expression>) {
<result1-to-be-matched> {<action>}
<result2-to-be-matched> {<action>}
}
switch
ステートメントの構文は、次のif
ステートメントに似ています。
if ("$(<result1-to-be-matched>)") -eq ("$(<test-expression>)") {<action>}
if ("$(<result2-to-be-matched>)") -eq ("$(<test-expression>)") {<action>}
式には、ブール値を返すリテラル値 (文字列または数値)、変数、スクリプトブロックが含まれます。
switch
ステートメントは、比較前にすべての値を文字列に変換します。 例については、この記事 で後述する文字列変換の影響 を参照してください。
<test-expression>
は式モードで評価されます。 式が配列や他の列挙可能な型などの複数の値を返す場合、 switch
ステートメントは列挙された各値を個別に評価します。
<result-to-be-matched>
は、式を 1 つの値に解決する必要があります。
その値は入力値と比較されます。
default
値は、他の一致がない場合に使用されるアクション用に予約されています。
switch
ステートメントでは、$_
と$switch
自動変数を使用できます。 自動変数には、 switch
ステートメントに渡される式の値が含まれており、 <result-to-be-matched>
ステートメントのスコープ内で評価および使用できます。 詳細については、「about_Automatic_Variables」を参照してください。
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
}
パラメーターを使用しない場合、switch
は Exact パラメーターの使用と同じように動作します。 値に対して大文字と小文字を区別しない一致が実行されます。 値がコレクションの場合、各要素は表示される順序で評価されます。
switch
ステートメントには、少なくとも 1 つの条件ステートメントを含める必要があります。
default
句は、値がいずれの条件にも一致しない場合にトリガーされます。 これは、else
ステートメントの if
句と同じです。 各default
ステートメントで許可されるswitch
句は 1 つだけです。
switch
には、次のパラメーターがあります。
- ワイルドカード - 条件がワイルドカード文字列であることを示します。 match 句が文字列でない場合、パラメーターは無視されます。 比較では大文字と小文字は区別されません。
- 正確な - match 句が文字列の場合は、完全に一致する必要があることを示します。 match 句が文字列でない場合、このパラメーターは無視されます。 比較では大文字と小文字は区別されません。
- CaseSensitive - 大文字と小文字が区別される一致を実行します。 match 句が文字列でない場合、このパラメーターは無視されます。
-
ファイル -
<test-expression>
ではなく、ファイルから入力を受け取ります。 ファイルは一度に 1 行ずつ読み取られ、switch
ステートメントによって評価されます。 既定では、比較では大文字と小文字が区別されません。 File パラメーターは、1 つのファイルのみをサポートします。 複数の File パラメーターが含まれている場合は、最後のパラメーターのみが使用されます。 詳細については、 File パラメーターの例を参照してください。 -
Regex - 値と条件の正規表現の照合を実行します。 match 句が文字列でない場合、このパラメーターは無視されます。
比較では大文字と小文字は区別されません。
$Matches
自動変数は、一致するステートメント ブロック内で使用できます。
注
RegexやWildcardなどの競合する値を指定する場合、指定された最後のパラメーターが優先され、競合するすべてのパラメーターは無視されます。 パラメーターの複数のインスタンスも許可されます。 ただし、リストされている最後のパラメーターのみが使用されます。
例示
次の例では、 switch
ステートメントの使用方法を示します。
単純な一致の例
次の例では、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.
break
とcontinue
を使用してフローを制御する
値が複数の条件と一致する場合は、各条件のアクションが実行されます。 この動作を変更するには、 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 ( ([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 プロパティは列挙体です。 列挙型は数値または文字列値と比較できますが、 switch
ステートメントは値を列挙型の文字列形式に変換します。
The string value matches a Thursday.
The expression matches a Thursday.
この動作は、-eq
ステートメントでのif
比較の動作とは異なります。
if (4 -eq ([datetime]'1 Jan 1970').DayOfWeek) {
'The integer value matches a Thursday.'
}
The value matches a Thursday.
この例では、ハッシュテーブルが switch
ステートメントに渡されます。
switch
は、ハッシュテーブルを文字列に変換します。
$test = @{
Test = 'test'
Test2 = 'test2'
}
$test.ToString()
System.Collections.Hashtable
ハッシュテーブルの文字列表現が Test キーの値と同じではないことに注意してください。
switch -Exact ($test) {
'System.Collections.Hashtable' { 'Hashtable string coercion' }
'test' { 'Hashtable value' }
}
Hashtable string coercion
switch
を使用してハッシュテーブル内の値をテストする
この例では、 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 ("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.
正規表現を使用する switch
次の例では、 -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!' }
}
でファイルの内容を読み取る switch
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
関連項目
PowerShell