Minden, amit valaha tudni akartál a switch
- 03/01/2021
- 12 perc olvasni
-
- s
- c
- x
Mint sok más nyelven, PowerShell van parancsok áramának végrehajtás belül yourscripts. Az egyik ilyen kijelentés a switch utasítás, a PowerShellben pedig olyan funkciókat kínál, amelyek más nyelveken nem találhatók meg. Ma mélyen belemerülünk a PowerShellswitch
munkájába.
Megjegyzés
a cikk eredeti változata megjelent a @KevinMarquette által írt blogban. ThePowerShell csapat köszönöm Kevin megosztására ezt a tartalmat velünk. Kérjük, nézd meg a blogját atPowerShellExplained.com.
az if utasítás
az egyik első kijelentés, amelyet megtanulsz, a if
utasítás. Ez lehetővé teszi, hogy végre egy script blockha egy utasítás $true
.
if ( Test-Path $Path ){ Remove-Item $Path}
a elseif
és else
kijelentések használatával sokkal bonyolultabb logikával rendelkezhet. Itt van egy példa, ahol van egy numerikus értéket a hét napján, és azt akarom, hogy a név, mint egy string.
$day = 3if ( $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
kiderül, hogy ez egy közös minta, és ennek számos módja van. Ezek közül az egyik egy switch
.
Switch statement
aswitch
utasítás lehetővé teszi, hogy egy változó és egy listát a lehetséges értékeket. Ha a valuematches a változó, akkor a scriptblock végrehajtásra kerül.
$day = 3switch ( $day ){ 0 { $result = 'Sunday' } 1 { $result = 'Monday' } 2 { $result = 'Tuesday' } 3 { $result = 'Wednesday' } 4 { $result = 'Thursday' } 5 { $result = 'Friday' } 6 { $result = 'Saturday' }}$result
'Wednesday'
ebben a példában a $day
értéke megegyezik a numerikus értékek egyikével, majd a helyes név $result
. Ebben a példában csak változó hozzárendelést végzünk, de minden PowerShell végrehajtható ezekben a szkriptblokkokban.
hozzárendelése egy
változóhoz az utolsó példát más módon írhatjuk.
$result = switch ( $day ){ 0 { 'Sunday' } 1 { 'Monday' } 2 { 'Tuesday' } 3 { 'Wednesday' } 4 { 'Thursday' } 5 { 'Friday' } 6 { 'Saturday' }}
az értéket a PowerShell csővezetékre helyezzük, és hozzárendeljük a $result
– hoz. Ugyanezt megteheti a if
és foreach
utasításokkal.
Default
a default
kulcsszó segítségével azonosíthatjuk, hogy mi történjen, ha nincs mérkőzés.
$result = switch ( $day ){ 0 { 'Sunday' } # ... 6 { 'Saturday' } default { 'Unknown' }}
itt visszaadjuk a Unknown
értéket az alapértelmezett esetben.
karakterláncok
az utolsó példákban a számokat illesztettem, de a karakterláncokat is össze lehet illeszteni.
$item = 'Role'switch ( $item ){ Component { 'is a component' } Role { 'is a role' } Location { 'is a location' }}
is a role
úgy döntöttem, hogy nem csomagolom be a Component
és Location
idéz időket, hogy kiemelje, hogyezek nem kötelező. A switch
ezeket a legtöbb esetben karakterláncként kezeli.
tömbök
a PowerShell egyik hűvös tulajdonsága switch
A tömbök kezelése. Ha egyswitch
tömböt ad meg, akkor a gyűjtemény minden elemét feldolgozza.
$roles = @('WEB','Database')switch ( $roles ) { 'Database' { 'Configure SQL' } 'WEB' { 'Configure IIS' } 'FileServer' { 'Configure Share' }}
Configure IISConfigure SQL
ha ismételt elemek vannak a tömbben, akkor azokat többször illesztik a megfelelő szakaszhoz.
PSItem
a$PSItem
vagy$_
hivatkozhat a feldolgozott aktuális elemre. Amikor asimple match-et csinálunk, $PSItem
az az érték, amelyet illesztünk. Néhány speciális mérkőzést fogok végrehajtani a következő szakaszban, ahol ezt a változót használják.
paraméterek
a PowerShell switch
egyedülálló tulajdonsága, hogy számos kapcsoló paraméterrel rendelkezikváltoztassa meg, hogyan működik.
-CaseSensitive
a mérkőzések alapértelmezés szerint nem esetérzékenyek. Ha ügyérzékenynek kell lennie, használhatja a-CaseSensitive
. Ezt fel lehet használni együtt a többi kapcsoló paraméterek.
– helyettesítő
engedélyezhetjük a helyettesítő támogatást a -wildcard
kapcsolóval. Ez ugyanazt a helyettesítő logikát használja, mint a-like
operátor minden mérkőzés elvégzéséhez.
$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
itt feldolgozunk egy üzenetet, majd a tartalom alapján különböző adatfolyamokon adjuk ki.
– Regex
a switch utasítás ugyanúgy támogatja a regex egyezést, mint a Joker.
switch -Regex ( $message ){ '^Error' { Write-Error -Message $Message } '^Warning' { Write-Warning -Message $Message } default { Write-Information $message }}
Több példa van a regex használatára egy másik cikkben, amelyet írtam: a regex használatának számos módja.
– File
a switch utasítás kevéssé ismert jellemzője, hogy képes feldolgozni egy fájlt a -File
paraméterrel. A-file
fájlt használja egy fájl elérési útjával, ahelyett, hogy változó kifejezést adna neki.
switch -Wildcard -File $path{ 'Error*' { Write-Error -Message $PSItem } 'Warning*' { Write-Warning -Message $PSItem } default { Write-Output $PSItem }}
úgy működik, mint egy tömb feldolgozása. Ebben a példában kombinálom a helyettesítő illesztéssel éshasználja a $PSItem
. Ez egy naplófájlt dolgoz fel, majd a regex-egyezésektől függően figyelmeztető és hibajelzésekre konvertálja.
Advanced details
most, hogy tudatában van ezeknek a dokumentált funkcióknak, felhasználhatjuk őket a fejlettebb feldolgozás összefüggésében.
kifejezések
aswitch
lehet egy kifejezés helyett egy változó.
switch ( ( Get-Service | Where status -eq 'running' ).name ) {...}
bármi legyen is a kifejezés kiértékelése, a mérkőzéshez használt érték.
több mérkőzés
lehet, hogy már felvette ezt, de a switch
több feltételnek is megfelelhet. Ez különösen igaz a -wildcard
vagy -regex
mérkőzések használatakor. Ugyanazt az állapotot adhatja hozzá többször isés mindegyik aktiválódik.
switch ( 'Word' ){ 'word' { 'lower case word match' } 'Word' { 'mixed case word match' } 'WORD' { 'upper case word match' }}
lower case word matchmixed case word matchupper case word match
mindhárom kijelentés ki van rúgva. Ez azt mutatja, hogy minden feltétel be van jelölve (sorrendben). Ez igaz a tömbök feldolgozására, ahol minden elem ellenőrzi az egyes feltételeket.
Folytatás
általában itt vezetném be a nyilatkozatot, de jobb, ha megtanuljuk, hogyan kell használni acontinue
először. Csakúgy, mint aforeach
loop,continue
folytatódik a következő elemreA gyűjtemény vagy kilép aswitch
ha nincs több elem. Ezt az utolsó példát újraírhatjuk a folyamatos kijelentésekkel, hogy csak egy nyilatkozat hajtson végre.
switch ( 'Word' ){ 'word' { 'lower case word match' continue } 'Word' { 'mixed case word match' continue } 'WORD' { 'upper case word match' continue }}
lower case word match
ahelyett, hogy mind a három elemet összeillesztené, az első párosul, és a kapcsoló tovább folytatódik a következő értékre. Mivel nincsenek feldolgozandó értékek, a kapcsoló kilép. Ez a következő példa a showinghow egy helyettesítő is egyezik több elem.
switch -Wildcard -File $path{ '*Error*' { Write-Error -Message $PSItem continue } '*Warning*' { Write-Warning -Message $PSItem continue } default { Write-Output $PSItem }}
mivel a bemeneti fájlban egy sor tartalmazhat mind a Error
és Warning
szót, csak azt akarjuk, hogy az első végrehajtsa, majd folytassa a fájl feldolgozását.
Break
a utasítás kilép a kapcsolóból. Ez ugyanaz a viselkedés, mint a continue
bemutatja a singlevalues. A különbség egy tömb feldolgozásakor jelenik meg. break
leállítja az összes feldolgozást a kapcsolóbanés continue
a következő elemre lép.
$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 updateWARNING: Ran into errors downloading filewrite-error -message $PSItem : Error: out of disk space+ CategoryInfo : NotSpecified: (:) , WriteErrorException+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
ebben az esetben, ha olyan sorokat érintünk, amelyek – vel kezdődnek, akkor hibát kapunk, és a kapcsoló leáll.Ez az, amit abreak
nyilatkozat tesz számunkra. Ha aError
– t találjuk a karakterlánc belsejében, nemcsak az elején, figyelmeztetésként írjuk. Ugyanezt tesszük a Warning
esetén is. Lehetséges, hogy egy sornak mind a Error
, mind a Warning
szója lehet, de csak egy folyamat szükséges. Ez az, amit a continue
nyilatkozat tesz számunkra.
Break címkék
a switch
nyilatkozat támogatja break/continue
címkék, mint a 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 } }}
személy szerint nem szeretem a töréscímkék használatát, de szerettem volna rámutatni rájuk, mert ‘ reconfusing, ha még soha nem látta őket. Ha több switch
vagy foreach
kijelentésekamelyek beágyazott, érdemes kitörni több, mint a belső legtöbb elem. Elhelyezhet egy labelon a switch
– t, amely a célpontja lehet.
Enum
PowerShell 5.0 adott nekünk enums és tudjuk használni őket egy kapcsolót.
enum Context { Component Role Location}$item = ::Roleswitch ( $item ){ Component { 'is a component' } Role { 'is a role' } Location { 'is a location' }}
is a role
ha mindent olyan erősen gépelt enumként szeretne tartani, akkor zárójelbe teheti őket.
switch ($item ){ (::Component) { 'is a component' } (::Role) { 'is a role' } (::Location) { 'is a location' }}
a zárójelekre itt van szükség, hogy a kapcsoló ne kezelje a ::Location
ASA szó karakterláncot.
ScriptBlock
használhatunk egy scriptblock-ot, hogy szükség esetén elvégezzük a mérkőzés értékelését.
$age = 37switch ( $age ){ {$PSItem -le 18} { 'child' } {$PSItem -gt 18} { 'adult' }}
'adult'
Ez bonyolultabbá teszi a switch
nehezen olvasható. A legtöbb esetben, ha ilyet használsz, jobb lenne a if
és elseif
nyilatkozatok használata. Érdemes lenne ezt használni, ha már Lenne egy nagy kapcsoló a helyén, és két elemre lenne szükségem, hogy ugyanazt az értékelést elérjem.
egy dolog, ami szerintem segít az olvashatóságban, a szkriptblokk zárójelbe helyezése.
switch ( $age ){ ({$PSItem -le 18}) { 'child' } ({$PSItem -gt 18}) { 'adult' }}
továbbra is ugyanúgy működik, és jobb vizuális szünetet biztosít, ha gyorsan nézzük.
Regex $mérkőzések
felül kell vizsgálnunk a regex-et, hogy megérintsünk valamit, ami nem azonnal nyilvánvaló. A regexpopulálja a $matches
változót. Én megy a használata $matches
több, amikor beszéleka sok módon lehet használni regex. Itt van egy gyors minta, amely megmutatja azt akcióban a megnevezett mérkőzésekkel.
$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-3456WARNING: message may contain a credit card number: 1234-5678-1234-5678
$null
akkor egyezik a $null
érték, amely nem kell az alapértelmezett.
$value = $nullswitch ( $value ){ $null { 'Value is null' } default { 'value is not null' }}```OutputValue is null
ugyanez vonatkozik egy üres karakterláncra is.
switch ( '' ){ '' { 'Value is empty' } default { 'value is a empty string' }}```OutputValue is empty
konstans expression
Lee Dailey rámutatott, hogy egy konstans $true
kifejezést használhatunk a elemek értékeléséhez.Képzelje el, ha több logikai ellenőrzésünk van, amelyeknek meg kell történniük.
$isVisible = $false$isEnabled = $true$isSecure = $trueswitch ( $true ){ $isEnabled { 'Do-Action' } $isVisible { 'Show-Animation' } $isSecure { 'Enable-AdminMenu' }}
Do-ActionEnabled-AdminMenu
Ez egy tiszta módja annak, hogy értékelje, és tegyen lépéseket az állapota több logikai mezők. A lényeg ebben az, hogy egy mérkőzés megfordíthatja egy olyan érték állapotát, amelyet még nem értékeltek.
$isVisible = $false$isEnabled = $true$isAdmin = $falseswitch ( $true ){ $isEnabled { 'Do-Action' $isVisible = $true } $isVisible { 'Show-Animation' } $isAdmin { 'Enable-AdminMenu' }}
Do-ActionShow-Animation
Beállítás $isEnabled
$true
ebben a példában meggyőződhet arról, hogy a $isVisible
is be van állítva$true
. Ezután, amikor a $isVisible
kiértékelésre kerül, a scriptblock meghívásra kerül. Ez egy bitcounter-intuitív, de a mechanika okos használata.
$switch automatikus változó
amikor a switch
feldolgozza értékeit, létrehoz egy enumeratort, és $switch
– nek nevezi. Ez a PowerShell által létrehozott automatikus változó, amelyet közvetlenül manipulálhat.
$a = 1, 2, 3, 4switch($a) { 1 { $switch.MoveNext(); $switch.Current } 3 { $switch.MoveNext(); $switch.Current }}
Ez a következő eredményeket adja meg:
24
az enumerator előre mozgatásával a következő elem nem kerül feldolgozásra a switch
de ezt az értéket közvetlenül el tudja fogadni. Őrültségnek nevezném.
egyéb minták
Hashtables
az egyik legnépszerűbb hozzászólásom a hashtables-en. Ahashtable
egyik felhasználási esete a keresési táblázat. Ez egy alternatív megközelítés egy közös mintához, amelyet aswitch
utasítás gyakran címez.
$day = 3$lookup = @{ 0 = 'Sunday' 1 = 'Monday' 2 = 'Tuesday' 3 = 'Wednesday' 4 = 'Thursday' 5 = 'Friday' 6 = 'Saturday'}$lookup
Wednesday
Ha csak egy switch
keresést használok, gyakran használok egy hashtable
helyett.
Enum
PowerShell 5.0 bevezette aEnum
– t, és ez is egy lehetőség ebben az esetben.
$day = 3enum DayOfTheWeek { Sunday Monday Tuesday Wednesday Thursday Friday Saturday}$day
Wednesday
egész nap különböző módszereket kereshetünk a probléma megoldására. Csak tudni akartam, hogy van-e választásod.
záró szavak
a kapcsolási utasítás egyszerű a felületen, de olyan fejlett funkciókat kínál, amelyeket a legtöbb ember nem ismer fel. Ezeknek a funkcióknak a összekapcsolása erőteljes funkciót jelent. Remélem, tanultál valamit, amit korábban nem vettél észre.