Switch 문에 대해 알고 싶은 모든 것
다른 많은 언어처럼 PowerShell에도 스크립트 내의 실행 흐름을 제어하는 명령이 있습니다. 이러한 문 중 하나는 switch 문이며 PowerShell에서는 다른 언어에서 찾을 수 없는 기능을 제공합니다. 현재 PowerShell switch
작업에 대해 자세히 알아보겠습니다.
참고 항목
현재 문서의 원본 버전은 @KevinMarquette가 작성한 블로그에 있습니다. PowerShell 팀은 이 콘텐츠를 공유해 주신 Kevin에게 감사드립니다. PowerShellExplained.com에 있는 그의 블로그를 확인하세요.
if
문
학습하는 첫 번째 문 중 하나는 문입니다 if
. 문인 경우 스크립트 블록을 실행할 수 있습니다 $true
.
if ( Test-Path $Path )
{
Remove-Item $Path
}
elseif
및 else
문을 사용하여 훨씬 더 복잡한 논리를 만들 수 있습니다. 다음은 요일의 숫자 값이 있고 이름을 문자열로 가져오는 예제입니다.
$day = 3
if ( $day -eq 0 ) { $result = 'Sunday' }
elseif ( $day -eq 1 ) { $result = 'Monday' }
elseif ( $day -eq 2 ) { $result = 'Tuesday' }
elseif ( $day -eq 3 ) { $result = 'Wednesday' }
elseif ( $day -eq 4 ) { $result = 'Thursday' }
elseif ( $day -eq 5 ) { $result = 'Friday' }
elseif ( $day -eq 6 ) { $result = 'Saturday' }
$result
Wednesday
이것은 일반적인 패턴이며 처리하는 방법은 대단히 다양합니다. 그 중 하나는 .switch
switch 문
이 switch
문을 사용하면 변수와 가능한 값 목록을 제공할 수 있습니다. 값이 변수와 일치하면 관련 scriptblock이 실행됩니다.
$day = 3
switch ( $day )
{
0 { $result = 'Sunday' }
1 { $result = 'Monday' }
2 { $result = 'Tuesday' }
3 { $result = 'Wednesday' }
4 { $result = 'Thursday' }
5 { $result = 'Friday' }
6 { $result = 'Saturday' }
}
$result
'Wednesday'
이 예제에서 값은 $day
숫자 값 중 하나와 일치한 다음 올바른 이름이 할당됩니다 $result
. 이 예제에서는 변수 할당만 수행하지만 이러한 스크립트 블록에서는 어떤 PowerShell도 실행할 수 있습니다.
변수에 할당
마지막 예제를 다른 방법으로 작성할 수 있습니다.
$result = switch ( $day )
{
0 { 'Sunday' }
1 { 'Monday' }
2 { 'Tuesday' }
3 { 'Wednesday' }
4 { 'Thursday' }
5 { 'Friday' }
6 { 'Saturday' }
}
지금은 PowerShell 파이프라인에 값을 배치하고 이 값을 $result
에 할당합니다. 및 foreach
문을 사용하여 이 작업을 if
수행할 수 있습니다.
기본값
키워드(keyword) 사용하여 default
일치하는 항목이 없는 경우 수행할 작업을 식별할 수 있습니다.
$result = switch ( $day )
{
0 { 'Sunday' }
# ...
6 { 'Saturday' }
default { 'Unknown' }
}
여기서는 기본 사례의 값을 Unknown
반환합니다.
문자열
마지막 예제에서 숫자와 일치했지만 문자열을 일치시킬 수도 있습니다.
$item = 'Role'
switch ( $item )
{
Component
{
'is a component'
}
Role
{
'is a role'
}
Location
{
'is a location'
}
}
is a role
나는 포장 Component
하지 않기로 결정하고,Role
Location
그들이 선택 사항임을 강조하기 위해 여기에 따옴표로 일치합니다. 대부분의 switch
경우 문자열로 처리합니다.
배열
PowerShell switch
의 멋진 기능 중 하나는 배열을 처리하는 방식입니다. 배열을 switch
제공하면 해당 컬렉션의 각 요소를 처리합니다.
$roles = @('WEB','Database')
switch ( $roles ) {
'Database' { 'Configure SQL' }
'WEB' { 'Configure IIS' }
'FileServer' { 'Configure Share' }
}
Configure IIS
Configure SQL
배열에 반복된 항목이 있다면 관련 섹션에서 여러 번 일치됩니다.
PSItem
$PSItem
또는 $_
를 사용하면 처리된 현재 항목을 참조할 수 있습니다. 단순 일치를 수행할 때 $PSItem
는 일치시키는 값입니다. 이 변수가 사용되는 다음 섹션에서 몇 가지 고급 일치를 수행합니다.
매개 변수
PowerShell switch
의 고유한 기능은 성능 방식을 변경하는 여러 스위치 매개 변수가 있다는 것입니다.
-CaseSensitive
기본적으로 일치는 대/소문자를 구분하지 않습니다. 대/소문자를 구분 -CaseSensitive
해야 하는 경우 . 다른 스위치 매개 변수와 함께 사용할 수 있습니다.
-Wildcard
스위치를 사용하여 wild카드 지원을 -wildcard
사용하도록 설정할 수 있습니다. 이렇게 하면 각 일치 작업을 수행하는 연산자로 -like
동일한 야생카드 논리가 사용됩니다.
$Message = 'Warning, out of disk space'
switch -Wildcard ( $message )
{
'Error*'
{
Write-Error -Message $Message
}
'Warning*'
{
Write-Warning -Message $Message
}
default
{
Write-Information $message
}
}
WARNING: Warning, out of disk space
여기서는 메시지를 처리한 다음 내용에 따라 서로 다른 스트림에 출력합니다.
-Regex
switch 문은 야생처럼 regex 일치를 지원합니다카드.
switch -Regex ( $message )
{
'^Error'
{
Write-Error -Message $Message
}
'^Warning'
{
Write-Warning -Message $Message
}
default
{
Write-Information $message
}
}
내가 쓴 다른 문서에서 regex를 사용하는 더 많은 예가 있습니다: regex를 사용하는 여러 가지 방법입니다.
-File
switch 문의 알려진 기능은 매개 변수를 사용하여 파일을 처리할 수 있다는 것입니다 -File
. 변수 식을 제공하는 대신 파일의 경로와 함께 사용합니다 -file
.
switch -Wildcard -File $path
{
'Error*'
{
Write-Error -Message $PSItem
}
'Warning*'
{
Write-Warning -Message $PSItem
}
default
{
Write-Output $PSItem
}
}
배열 처리와 비슷한 방식으로 작동합니다. 이 예제에서는 wild카드 일치와 결합하고 $PSItem
사용합니다. 이렇게 하면 로그 파일이 처리되고 regex 일치 항목에 따라 경고 및 오류 메시지로 변환됩니다.
고급 세부 정보
이제 이러한 문서화된 모든 기능을 인식했으므로 고급 처리의 컨텍스트에서 사용할 수 있습니다.
식
변수 switch
대신 식에 있을 수 있습니다.
switch ( ( Get-Service | Where status -eq 'running' ).name ) {...}
식의 평가 대상은 일치에 사용한 값이 됩니다.
여러 일치 항목
이미 이를 선택했을 수 있지만 switch
여러 조건과 일치할 수 있습니다. 사용하거나 -regex
일치할 때 -wildcard
특히 그렇습니다. 동일한 조건을 여러 번 추가할 수 있으며 이 경우 모든 조건이 트리거됩니다.
switch ( 'Word' )
{
'word' { 'lower case word match' }
'Word' { 'mixed case word match' }
'WORD' { 'upper case word match' }
}
lower case word match
mixed case word match
upper case word match
이러한 세 문은 모두 발생합니다. 이는 모든 조건이 순서대로 검사 것을 보여 줍니다. 이는 각 항목이 각 조건을 검사 배열을 처리하는 경우 마찬가지입니다.
계속
일반적으로, 이것은 내가 문을 소개 break
할 곳이지만, 우리가 먼저 사용하는 continue
방법을 배우는 것이 좋습니다. 루프 continue
와 foreach
마찬가지로 컬렉션의 다음 항목으로 계속 이동하거나 항목이 더 이상 없으면 종료합니다switch
. 마지막 예제를 continue 문으로 다시 작성하여 하나의 문만 실행할 수 있습니다.
switch ( 'Word' )
{
'word'
{
'lower case word match'
continue
}
'Word'
{
'mixed case word match'
continue
}
'WORD'
{
'upper case word match'
continue
}
}
lower case word match
세 항목을 모두 일치시키는 대신 첫 번째 항목이 일치하고 스위치가 다음 값으로 계속됩니다. 처리할 값이 없으므로 스위치가 종료됩니다. 다음 예제에서는 야생카드 여러 항목과 일치할 수 있는 방법을 보여 줍니다.
switch -Wildcard -File $path
{
'*Error*'
{
Write-Error -Message $PSItem
continue
}
'*Warning*'
{
Write-Warning -Message $PSItem
continue
}
default
{
Write-Output $PSItem
}
}
입력 파일의 줄에 단어와 Warning
단어가 Error
모두 포함될 수 있으므로 첫 번째 줄만 실행한 다음 파일 처리를 계속하려고 합니다.
휴식 시간
break
문이 스위치를 종료합니다. continue
가 단일 값에 대해 제공하는 동작과 동일합니다. 배열을 처리할 때 차이가 표시됩니다. break
는 스위치의 모든 처리를 중지하고 continue
다음 항목으로 이동합니다.
$Messages = @(
'Downloading update'
'Ran into errors downloading file'
'Error: out of disk space'
'Sending email'
'...'
)
switch -Wildcard ($Messages)
{
'Error*'
{
Write-Error -Message $PSItem
break
}
'*Error*'
{
Write-Warning -Message $PSItem
continue
}
'*Warning*'
{
Write-Warning -Message $PSItem
continue
}
default
{
Write-Output $PSItem
}
}
Downloading update
WARNING: Ran into errors downloading file
write-error -message $PSItem : Error: out of disk space
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
이 경우 Error
로 시작하는 줄에 도달하면 오류가 발생하고 switch가 중단됩니다.
이것이 바로 그 break
진술이 우리를 위해 하는 일입니다. 문자열 내에 Error
가 있고 시작 부분이 아니라면 이를 경고라고 작성합니다. 우리는 에 대해 같은 일을합니다 Warning
. 한 줄에 Error
와 Warning
단어가 모두 포함될 수 있지만 하나만 처리하면 됩니다. continue
문은 바로 이 작업을 수행합니다.
레이블 중단
문은 switch
다음과 같은 foreach
레이블을 지원 break/continue
합니다.
:filelist foreach($path in $logs)
{
:logFile switch -Wildcard -File $path
{
'Error*'
{
Write-Error -Message $PSItem
break filelist
}
'Warning*'
{
Write-Error -Message $PSItem
break logFile
}
default
{
Write-Output $PSItem
}
}
}
나는 개인적으로 브레이크 레이블의 사용을 좋아하지 않는다하지만 난 당신이 전에 그들을 본 적이 없다면 그들은 혼란 때문에 그들을 지적하고 싶었다. 중첩된 여러 switch
문 또는 foreach
문이 있는 경우 가장 안쪽 항목보다 많은 항목을 분리할 수 있습니다. 대상이 될 수 있는 레이블을 switch
배치할 수 있습니다 break
.
열거형
PowerShell 5.0은 열거형을 제공했으며 스위치에서 사용할 수 있습니다.
enum Context {
Component
Role
Location
}
$item = [Context]::Role
switch ( $item )
{
Component
{
'is a component'
}
Role
{
'is a role'
}
Location
{
'is a location'
}
}
is a role
모든 항목을 강력한 형식의 열거형으로 유지하려는 경우 괄호 안에 배치할 수 있습니다.
switch ($item )
{
([Context]::Component)
{
'is a component'
}
([Context]::Role)
{
'is a role'
}
([Context]::Location)
{
'is a location'
}
}
여기서는 스위치가 값을 [Context]::Location
리터럴 문자열로 처리하지 않도록 괄호가 필요합니다.
ScriptBlock
필요하다면 scriptblock을 사용하여 일치 항목 평가를 수행할 수 있습니다.
$age = 37
switch ( $age )
{
{$PSItem -le 18}
{
'child'
}
{$PSItem -gt 18}
{
'adult'
}
}
'adult'
이렇게 하면 복잡성이 더해지고 읽기가 어려울 수 있습니다 switch
. 이와 같은 요소를 사용하는 대부분의 경우에는 if
및 elseif
문을 사용하는 것이 좋습니다. 이미 큰 스위치가 있고 동일한 평가 블록에 충돌하기 위해 두 개의 항목이 필요한 경우 이를 사용하는 것이 좋습니다.
가독성을 높일 수 있는 한 가지 방법은 scriptblock을 괄호 안에 넣는 것입니다.
switch ( $age )
{
({$PSItem -le 18})
{
'child'
}
({$PSItem -gt 18})
{
'adult'
}
}
여전히 동일한 방식으로 실행되며 빠르게 살펴볼 때 더 나은 시각적 중단을 제공합니다.
Regex $matches
우리는 즉시 명확하지 않은 무언가를 만지려면 regex를 다시 방문해야합니다. regex를 사용하면 변수가 $matches
채워집니다. 나는 regex를 사용하는 $matches
여러 가지 방법에 대해 이야기 할 때 더 많은 사용에 간다. 다음은 명명된 일치 항목의 작동을 보여 줄 빠른 샘플입니다.
$message = 'my ssn is 123-23-3456 and credit card: 1234-5678-1234-5678'
switch -regex ($message)
{
'(?<SSN>\d\d\d-\d\d-\d\d\d\d)'
{
Write-Warning "message contains a SSN: $($matches.SSN)"
}
'(?<CC>\d\d\d\d-\d\d\d\d-\d\d\d\d-\d\d\d\d)'
{
Write-Warning "message contains a credit card number: $($matches.CC)"
}
'(?<Phone>\d\d\d-\d\d\d-\d\d\d\d)'
{
Write-Warning "message contains a phone number: $($matches.Phone)"
}
}
WARNING: message may contain a SSN: 123-23-3456
WARNING: message may contain a credit card number: 1234-5678-1234-5678
$null
기본값이 아니어도 되는 $null
값을 일치시킬 수 있습니다.
$values = '', 5, $null
switch ( $values )
{
$null { "Value '$_' is `$null" }
{ '' -eq $_ } { "Value '$_' is an empty string" }
default { "Value [$_] isn't an empty string or `$null" }
}
Value '' is an empty string
Value [5] isn't an empty string or $null
Value '' is $null
switch
문에서 빈 문자열을 테스트할 때는 ''
원시 값 대신 이 예제와 같이 비교 문을 사용하는 것이 중요합니다. switch
문에서 원시 값 ''
도 $null
과 일치합니다. 예시:
$values = '', 5, $null
switch ( $values )
{
$null { "Value '$_' is `$null" }
'' { "Value '$_' is an empty string" }
default { "Value [$_] isn't an empty string or `$null" }
}
Value '' is an empty string
Value [5] isn't an empty string or $null
Value '' is $null
Value '' is an empty string
또한 cmdlet의 빈 반환에 주의해야 합니다. 출력이 없는 cmdlet 또는 파이프라인은 default
사례를 포함하여 아무것도 일치하지 않는 빈 배열로 처리됩니다.
$file = Get-ChildItem NonExistantFile*
switch ( $file )
{
$null { '$file is $null' }
default { "`$file is type $($file.GetType().Name)" }
}
# No matches
상수 식
Lee Dailey는 상수 $true
식을 사용하여 항목을 평가할 [bool]
수 있다고 지적했습니다.
몇 가지 부울 검사 발생해야 한다고 상상해 보십시오.
$isVisible = $false
$isEnabled = $true
$isSecure = $true
switch ( $true )
{
$isEnabled
{
'Do-Action'
}
$isVisible
{
'Show-Animation'
}
$isSecure
{
'Enable-AdminMenu'
}
}
Do-Action
Enabled-AdminMenu
이는 여러 부울 필드의 상태 평가하고 조치를 취하는 클린 방법입니다. 이에 대한 멋진 점은 하나의 일치 항목이 아직 평가되지 않은 값의 상태 대칭 이동되도록 할 수 있다는 것입니다.
$isVisible = $false
$isEnabled = $true
$isAdmin = $false
switch ( $true )
{
$isEnabled
{
'Do-Action'
$isVisible = $true
}
$isVisible
{
'Show-Animation'
}
$isAdmin
{
'Enable-AdminMenu'
}
}
Do-Action
Show-Animation
이 예제에서 설정 $isEnabled
하면 $true
해당 $isVisible
설정도 .로 설정됩니다 $true
.
$isVisible
그런 다음 평가되면 해당 scriptblock이 호출됩니다. 이것은 약간 직관적이지 않지만 역학을 영리하게 사용합니다.
자동 변수 $switch
switch
값을 처리할 때 열거자를 만들고 호출합니다$switch
. 이것은 PowerShell에서 자동으로 생성되는 변수이며 사용자가 직접 조작할 수 있습니다.
$a = 1, 2, 3, 4
switch($a) {
1 { [void]$switch.MoveNext(); $switch.Current }
3 { [void]$switch.MoveNext(); $switch.Current }
}
그러면 다음과 같은 결과가 표시됩니다.
2
4
열거자를 앞으로 이동하면 다음 항목이 처리되지 않지만 해당 값에 switch
직접 액세스할 수 있습니다. 나는 그것을 광기라고 부를 것이다.
기타 패턴
해시 테이블
내 가장 인기있는 게시물 중 하나는 내가 해시 테이블에서 한 것입니다. 한 가지 사용 사례 hashtable
중 하나는 조회 테이블이 되는 것입니다. switch
문이 자주 처리하는 일반적인 패턴에 대한 또 다른 접근 방식입니다.
$day = 3
$lookup = @{
0 = 'Sunday'
1 = 'Monday'
2 = 'Tuesday'
3 = 'Wednesday'
4 = 'Thursday'
5 = 'Friday'
6 = 'Saturday'
}
$lookup[$day]
Wednesday
switch
를 조회로만 사용할 때는 주로 hashtable
를 대신 사용합니다.
열거형
PowerShell 5.0에서 도입된 Enum
을 이 경우에도 사용할 수 있습니다.
$day = 3
enum DayOfTheWeek {
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
}
[DayOfTheWeek]$day
Wednesday
이 문제를 해결하는 방법을 모두 살펴보려면 종일 해도 모자랄 것입니다. 여러분에게 이러한 선택지가 있음을 알려드리고 싶을 뿐입니다.
마지막 단어
스위치 문은 표면에서 간단하지만 대부분의 사람들이 인식하지 못하는 몇 가지 고급 기능을 제공합니다. Switch 문은 이러한 기능을 함께 사용할 때 강력한 효과를 발휘합니다. 난 당신이 전에 실현하지 않은 무언가를 배웠으면 좋겠다.
PowerShell
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기