Semua yang anda inginkan untuk mengetahui tentang pernyataan switch
Seperti banyak bahasa lain, PowerShell memiliki perintah untuk mengontrol alur eksekusi dalam skrip Anda. Salah satu pernyataan tersebut adalah pernyataan pengalihan dan di PowerShell, ia menawarkan fitur yang tidak ditemukan dalam bahasa lain. Hari ini, kami menyelam lebih dalam untuk bekerja dengan PowerShell switch
.
Catatan
Versi asli artikel ini muncul di blog yang ditulis oleh @KevinMarquette. Tim PowerShell berterima kasih kepada Kevin karena telah membagikan konten ini kepada kami. Silakan lihat blognya di PowerShellExplained.com.
Pernyataan if
Salah satu pernyataan pertama yang Anda pelajari adalah pernyataan .if
Ini memungkinkan Anda menjalankan blok skrip jika pernyataan adalah $true
.
if ( Test-Path $Path )
{
Remove-Item $Path
}
Anda dapat memiliki logika yang jauh lebih rumit menggunakan elseif
pernyataan dan else
. Berikut adalah contoh di mana saya memiliki nilai numerik untuk hari dalam seminggu dan saya ingin mendapatkan nama sebagai string.
$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
Ternyata ini adalah pola umum dan ada banyak cara untuk menangani hal ini. Salah satunya adalah dengan switch
.
Pernyataan beralih
Pernyataan ini switch
memungkinkan Anda untuk memberikan variabel dan daftar nilai yang mungkin. Jika nilai cocok dengan variabel, maka blok skripnya dijalankan.
$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'
Untuk contoh ini, nilai cocok dengan $day
salah satu nilai numerik, maka nama yang benar ditetapkan ke $result
. Kami hanya melakukan penetapan variabel dalam contoh ini, tetapi PowerShell apa pun dapat dijalankan di blok skrip tersebut.
Menetapkan ke variabel
Kita dapat menulis contoh terakhir dengan cara lain.
$result = switch ( $day )
{
0 { 'Sunday' }
1 { 'Monday' }
2 { 'Tuesday' }
3 { 'Wednesday' }
4 { 'Thursday' }
5 { 'Friday' }
6 { 'Saturday' }
}
Kami menempatkan nilai pada alur PowerShell dan menetapkannya ke $result
. Anda dapat melakukan hal yang sama dengan if
pernyataan dan foreach
.
Default
Kita dapat menggunakan default
kata kunci untuk mengidentifikasi apa yang harus terjadi jika tidak ada kecocokan.
$result = switch ( $day )
{
0 { 'Sunday' }
# ...
6 { 'Saturday' }
default { 'Unknown' }
}
Di sini kita mengembalikan nilai Unknown
dalam kasus default.
String
Saya mencocokkan angka dalam contoh terakhir, tetapi Anda juga dapat mencocokkan string.
$item = 'Role'
switch ( $item )
{
Component
{
'is a component'
}
Role
{
'is a role'
}
Location
{
'is a location'
}
}
is a role
Saya memutuskan untuk tidak membungkus Component
,Role
dan Location
cocok dalam tanda kutip di sini untuk menyoroti bahwa mereka opsional. memperlakukan switch
mereka sebagai string dalam banyak kasus.
Larik
Salah satu fitur keren PowerShell switch
adalah caranya menangani array. Jika Anda memberikan switch
array, ia memproses setiap elemen dalam koleksi tersebut.
$roles = @('WEB','Database')
switch ( $roles ) {
'Database' { 'Configure SQL' }
'WEB' { 'Configure IIS' }
'FileServer' { 'Configure Share' }
}
Configure IIS
Configure SQL
Jika Anda memiliki item berulang dalam array Anda, maka item tersebut dicocokkan beberapa kali oleh bagian yang sesuai.
PSItem
Anda dapat menggunakan $PSItem
atau $_
untuk mereferensikan item saat ini yang diproses. Ketika kita melakukan kecocokan sederhana, $PSItem
adalah nilai yang kita cocokkan. Saya akan melakukan beberapa kecocokan lanjutan di bagian berikutnya tempat variabel ini digunakan.
Parameter
Fitur unik PowerShell adalah powerShell switch
memiliki sejumlah parameter pengalihan yang mengubah performanya.
-CaseSensitive
Kecocokan tidak peka huruf besar/kecil secara default. Jika Anda perlu peka huruf besar/kecil, Anda dapat menggunakan -CaseSensitive
. Ini dapat digunakan dalam kombinasi dengan parameter sakelar lainnya.
-Kartubebas
Kita dapat mengaktifkan dukungan kartubebas dengan sakelar -wildcard
. Ini menggunakan logika wildcard yang sama dengan -like
operator untuk melakukan setiap kecocokan.
$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
Di sini kami memproses pesan lalu mengeluarkannya pada aliran yang berbeda berdasarkan konten.
-Regex
Pernyataan switch mendukung kecocokan regex sama seperti wildcard.
switch -Regex ( $message )
{
'^Error'
{
Write-Error -Message $Message
}
'^Warning'
{
Write-Warning -Message $Message
}
default
{
Write-Information $message
}
}
Saya memiliki lebih banyak contoh penggunaan regex di artikel lain yang saya tulis: Banyak cara untuk menggunakan regex.
-File
Fitur yang sedikit diketahui dari pernyataan pengalihan adalah dapat memproses file dengan -File
parameter . Anda menggunakan -file
dengan jalur ke file alih-alih memberinya ekspresi variabel.
switch -Wildcard -File $path
{
'Error*'
{
Write-Error -Message $PSItem
}
'Warning*'
{
Write-Warning -Message $PSItem
}
default
{
Write-Output $PSItem
}
}
Ini berfungsi seperti memproses array. Dalam contoh ini, saya menggabungkannya dengan pencocokan kartubebas dan memanfaatkan $PSItem
. Ini akan memproses file log dan mengonversinya menjadi pesan peringatan dan kesalahan tergantung pada kecocokan regex.
Detail tingkat lanjut
Sekarang setelah Anda mengetahui semua fitur yang didokumentasikan ini, kita dapat menggunakannya dalam konteks pemrosesan yang lebih canggih.
Expressions
switch
dapat berada pada ekspresi alih-alih variabel.
switch ( ( Get-Service | Where status -eq 'running' ).name ) {...}
Apa pun yang dievaluasi oleh ekspresi adalah nilai yang digunakan untuk kecocokan.
Beberapa kecocokan
Anda mungkin telah mengambil ini, tetapi switch
dapat cocok dengan beberapa kondisi. Ini terutama berlaku saat menggunakan -wildcard
atau -regex
mencocokkan. Anda dapat menambahkan kondisi yang sama beberapa kali dan semuanya dipicu.
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
Ketiga pernyataan ini dipecat. Ini menunjukkan bahwa setiap kondisi diperiksa (secara berurutan). Ini berlaku untuk memproses array di mana setiap item memeriksa setiap kondisi.
Lanjutkan
Biasanya, di sinilah saya akan memperkenalkan break
pernyataan, tetapi lebih baik kita belajar cara menggunakannya continue
terlebih dahulu. Sama seperti dengan perulangan foreach
, continue
berlanjut ke item berikutnya dalam koleksi atau keluar switch
jika tidak ada item lagi. Kita dapat menulis ulang contoh terakhir tersebut dengan pernyataan lanjutan sehingga hanya satu pernyataan yang dijalankan.
switch ( 'Word' )
{
'word'
{
'lower case word match'
continue
}
'Word'
{
'mixed case word match'
continue
}
'WORD'
{
'upper case word match'
continue
}
}
lower case word match
Alih-alih mencocokkan ketiga item, item pertama cocok dan sakelar berlanjut ke nilai berikutnya. Karena tidak ada nilai yang tersisa untuk diproses, sakelar keluar. Contoh berikutnya adalah menunjukkan bagaimana kartubebas dapat mencocokkan beberapa item.
switch -Wildcard -File $path
{
'*Error*'
{
Write-Error -Message $PSItem
continue
}
'*Warning*'
{
Write-Warning -Message $PSItem
continue
}
default
{
Write-Output $PSItem
}
}
Karena baris dalam file input dapat berisi kata Error
dan Warning
, kami hanya ingin yang pertama dijalankan dan kemudian melanjutkan pemrosesan file.
Istirahat
Pernyataan break
keluar dari sakelar. Ini adalah perilaku yang sama yang continue
disajikan untuk nilai tunggal. Perbedaan ditunjukkan saat memproses array. break
menghentikan semua pemrosesan dalam sakelar dan continue
berpindah ke item berikutnya.
$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
Dalam hal ini, jika kita mencapai garis yang dimulai dengan Error
maka kita mendapatkan kesalahan dan tombol berhenti.
Inilah yang pernyataan itu break
lakukan untuk kita. Jika kita menemukan Error
di dalam string dan bukan hanya di awal, kita menulisnya sebagai peringatan. Kami melakukan hal yang sama untuk Warning
. Ada kemungkinan bahwa baris dapat memiliki kata Error
dan Warning
, tetapi kita hanya perlu satu untuk diproses. Inilah yang continue
dilakukan pernyataan untuk kita.
Putuskan label
Pernyataan ini switch
mendukung break/continue
label seperti foreach
.
: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
}
}
}
Saya pribadi tidak suka penggunaan break label tetapi saya ingin menunjukkannya karena mereka membingungkan jika Anda belum pernah melihatnya sebelumnya. Saat Anda memiliki beberapa switch
pernyataan atau foreach
yang ditumpuk, Anda mungkin ingin memecah lebih dari item paling dalam. Anda dapat menempatkan label pada switch
yang dapat menjadi target Anda break
.
Enum
PowerShell 5.0 memberi kami enum dan kami dapat menggunakannya dalam sakelar.
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
Jika Anda ingin menyimpan semuanya sebagai enum yang ditik dengan kuat, maka Anda dapat menempatkannya dalam tanda kurung.
switch ($item )
{
([Context]::Component)
{
'is a component'
}
([Context]::Role)
{
'is a role'
}
([Context]::Location)
{
'is a location'
}
}
Tanda kurung diperlukan di sini sehingga sakelar tidak memperlakukan nilai [Context]::Location
sebagai string harfiah.
ScriptBlock
Kita dapat menggunakan blok skrip untuk melakukan evaluasi untuk kecocokan jika diperlukan.
$age = 37
switch ( $age )
{
{$PSItem -le 18}
{
'child'
}
{$PSItem -gt 18}
{
'adult'
}
}
'adult'
Ini menambah kompleksitas dan dapat membuat Anda switch
sulit dibaca. Dalam kebanyakan kasus di mana Anda akan menggunakan sesuatu seperti ini akan lebih baik untuk digunakan if
dan elseif
pernyataan. Saya akan mempertimbangkan untuk menggunakan ini jika saya sudah memiliki sakelar besar di tempat dan saya membutuhkan dua item untuk mencapai blok evaluasi yang sama.
Satu hal yang saya pikir membantu dengan legibilitas adalah menempatkan blok skrip dalam tanda kurung.
switch ( $age )
{
({$PSItem -le 18})
{
'child'
}
({$PSItem -gt 18})
{
'adult'
}
}
Ini masih mengeksekusi dengan cara yang sama dan memberikan istirahat visual yang lebih baik ketika dengan cepat melihatnya.
$matches Regex
Kita perlu mengunjungi kembali regex untuk menyentuh sesuatu yang tidak segera jelas. Penggunaan regex mengisi $matches
variabel. Saya menggunakan lebih banyak $matches
ketika saya berbicara tentang Banyak cara untuk menggunakan regex. Berikut adalah sampel cepat untuk memperlihatkannya dalam tindakan dengan kecocokan bernama.
$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
Anda dapat mencocokkan $null
nilai yang tidak harus default.
$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
Saat menguji string kosong dalam switch
pernyataan, penting untuk menggunakan pernyataan perbandingan seperti yang ditunjukkan dalam contoh ini alih-alih nilai ''
mentah . Dalam pernyataan switch
, nilai ''
mentah juga cocok $null
dengan . Contohnya:
$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
Juga, berhati-hatilah dengan pengembalian kosong dari cmdlet. Cmdlet atau alur yang tidak memiliki output diperlakukan sebagai array kosong yang tidak cocok dengan apa pun, termasuk huruf besar/kecil default
.
$file = Get-ChildItem NonExistantFile*
switch ( $file )
{
$null { '$file is $null' }
default { "`$file is type $($file.GetType().Name)" }
}
# No matches
Ekspresi konstan
Lee Dailey menunjukkan bahwa kita dapat menggunakan ekspresi konstan $true
untuk mengevaluasi [bool]
item.
Bayangkan jika kita memiliki beberapa pemeriksaan boolean yang perlu terjadi.
$isVisible = $false
$isEnabled = $true
$isSecure = $true
switch ( $true )
{
$isEnabled
{
'Do-Action'
}
$isVisible
{
'Show-Animation'
}
$isSecure
{
'Enable-AdminMenu'
}
}
Do-Action
Enabled-AdminMenu
Ini adalah cara bersih untuk mengevaluasi dan mengambil tindakan pada status beberapa bidang boolean. Hal keren tentang ini adalah Anda dapat memiliki satu kecocokan membalikkan status nilai yang belum dievaluasi.
$isVisible = $false
$isEnabled = $true
$isAdmin = $false
switch ( $true )
{
$isEnabled
{
'Do-Action'
$isVisible = $true
}
$isVisible
{
'Show-Animation'
}
$isAdmin
{
'Enable-AdminMenu'
}
}
Do-Action
Show-Animation
Pengaturan $isEnabled
ke $true
dalam contoh ini memastikan bahwa $isVisible
juga diatur ke $true
.
Kemudian ketika $isVisible
dievaluasi, blok skripnya dipanggil. Ini sedikit kontra-intuitif tetapi merupakan penggunaan mekanisme yang cerdas.
$switch variabel otomatis
switch
Ketika memproses nilai-nilainya, ia membuat enumerator dan memanggilnya $switch
. Ini adalah variabel otomatis yang dibuat oleh PowerShell dan Anda dapat memanipulasinya secara langsung.
$a = 1, 2, 3, 4
switch($a) {
1 { [void]$switch.MoveNext(); $switch.Current }
3 { [void]$switch.MoveNext(); $switch.Current }
}
Ini memberi Anda hasil dari:
2
4
Dengan memindahkan enumerator ke depan, item berikutnya tidak diproses oleh tetapi Anda dapat mengakses nilai tersebut switch
secara langsung. Aku akan menyebutnya gila.
Pola lainnya
Hashtable
Salah satu posting saya yang paling populer adalah yang saya lakukan pada hashtable. Salah satu kasus penggunaan untuk hashtable
adalah menjadi tabel pencarian. Itu adalah pendekatan alternatif untuk pola umum yang sering diatasi oleh switch
pernyataan.
$day = 3
$lookup = @{
0 = 'Sunday'
1 = 'Monday'
2 = 'Tuesday'
3 = 'Wednesday'
4 = 'Thursday'
5 = 'Friday'
6 = 'Saturday'
}
$lookup[$day]
Wednesday
Jika saya hanya menggunakan switch
sebagai pencarian, saya sering menggunakan hashtable
sebagai gantinya.
Enum
PowerShell 5.0 memperkenalkan Enum
dan ini juga merupakan opsi dalam kasus ini.
$day = 3
enum DayOfTheWeek {
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
}
[DayOfTheWeek]$day
Wednesday
Kita bisa pergi sepanjang hari melihat berbagai cara untuk menyelesaikan masalah ini. Aku hanya ingin memastikan kau tahu kau punya pilihan.
Kata-kata akhir
Pernyataan switch sederhana di permukaan tetapi menawarkan beberapa fitur canggih yang tidak disadari sebagian besar orang tersedia. Meringkas fitur-fitur tersebut bersama-sama menjadikan ini fitur yang kuat. Kuharap kau mempelajari sesuatu yang belum kau sadari sebelumnya.
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk