Articles

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 PowerShellswitchmunká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 -Fileparamé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. breakleá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 Warningeseté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 switchfeldolgozza é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 switchkeresé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.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük