If
If (<test1>)
{<statement list 1>}
[elseif (<test2>)
{<statement list 2>}]
[else
{<statement list 3>}]
簡略寫法
<condition> ? <if-true> : <if-false>
Switch
基本語法
Switch ( <test-expression> ){
<result1-to-be-matched> {<action>}
<result2-to-be-matched> {<action>}
Default {<action>} # optional
}
特別參數及語法
Switch [-regex | -wildcard | -exact] [-casesensitive] ( <test-expression> ){
"string1" | number1 | variable1 | { <value-scriptblock1> } { <action-scriptblock> }
"string2" | number2 | variable2 | { <value-scriptblock2> } { <action-scriptblock> }
Default { <action-scriptblock> } # optional
}
從檔案取得資料
Switch [-regex | -wildcard | -exact] [-casesensitive] -file filename {
"string" | number | variable | { <value-scriptblock> } { <action-scriptblock> }
default { <action-scriptblock> } # optional
}
說明:
參數 | 說明 |
---|---|
-regex | <test-expression> 的符合條件是正規式;如果 <test-expression> 變數型態不是字串,此參數會無效 |
-wildcard | 使用萬用字元去比對,這裡不分大小寫;如果 <test-expression> 變數型態不是字串,此參數會無效 |
-exact | 必須完全符合字串大小寫;如果 <test-expression> 變數型態不是字串,此參數會無效 |
-casesensitive | 區分大小寫;如果 <test-expression> 變數型態不是字串,此參數會無效 |
-file | 從文字型檔案讀取每一行來比較,這裡不分大小寫 |
-
範例1:使用 Script Blocks 來媒合,Switch 會執行所有吻合條件的部分
$a = 1,2,3 $Variable = 2 Switch($Variable){ { $_ -in $a }{ "Variable is in Array" } { $_ -match "[0-9]" }{ "Variable is matched regexp" } { $_ -lt 10 -and $_ -gt 1 }{ "Variable is bigger than 1, and smaller than 10" } Default { "Otherwise" } }
-
範例二:要中斷Switch繼續媒合所有 Script Block,要使用 Break
$a = 1,2,3 $Variable = 2 Switch($Variable){ { $_ -in $a }{ "Variable is in Array" break } { $_ -match "[0-9]" }{ "Variable is matched regexp" break } { $_ -lt 10 -and $_ -gt 1 }{ "Variable is bigger than 1, and smaller than 10" break } Default { "Otherwise" } }
-
範例三:
$Variable = 42 Switch($Variable){ { 0..20 -contains $_ }{ "Variable is between 0~20" } { 21..40 -contains $_ }{ "Variable is between 21~40" } { 41..60 -contains $_ }{ "Variable is between 41~60" } { 61..80 -contains $_ }{ "Variable is between 61~80" } { 81..100 -contains $_ }{ "Variable is between 81~100" } Default{ "Variable is not in 0~100" } }
-
範例四:媒合條件為正規式
$month = (Get-Date).Month $month switch -regex ([string]$month) { "^[1-3]$" {"Q1"} "^[4-6]$" {"Q2"} "^[7-9]$" {"Q3"} "^1[0-2]$" {"Q4"} }
Comparison Operators 比較運算說明
比較 | 說明 |
---|---|
-and | 進行邏輯運算 AND |
-or | 進行邏輯運算 OR |
-not | 進行邏輯運算 NOT |
-xor | 進行邏輯運算 XOR,而非 bit XOR運算 |
-is | 判斷變數型態是否與比對的型態相同 |
-isnot | 判斷變數型態是否與比對的型態不相同 |
-like | 字串匹配通配符模式,忽略大小寫 |
-ilike | 字串匹配通配符模式,忽略大小寫 |
-clike | 字串匹配通配符模式,比較大小寫 |
-notlike | 字串與通配符模式不匹配,忽略大小寫 |
-inotlike | 字串與通配符模式不匹配,忽略大小寫 |
-cnotlike | 字串與通配符模式不匹配,比較大小寫 |
-match | 字串與正規表示式模式匹配,忽略大小寫 |
-imatch | 字串與正規表示式模式匹配,忽略大小寫 |
-cmatch | 字串與正規表示式模式匹配,比較大小寫 |
-notmatch | 字串與正規表示式模式不匹配,忽略大小寫 |
-inotmatch | 字串與正規表示式模式不匹配,忽略大小寫 |
-cnotmatch | 字串與正規表示式模式不匹配,比較大小寫 |
-in | 變數值存在於集合之中,忽略大小寫 |
-iin | 變數值存在於集合之中,忽略大小寫 |
-cin | 變數值存在於集合之中,比較大小寫 |
-notin | 變數值不存在於集合之中,忽略大小寫 |
-inotin | 變數值不存在於集合之中,忽略大小寫 |
-cnotin | 變數值不存在於集合之中,比較大小寫 |
-contains | 集合中包含變數值,忽略大小寫 |
-icontains | 集合中包含變數值,忽略大小寫 |
-ccontains | 集合中包含變數值,比較大小寫 |
-eq | Equal 等於(忽略大小寫) |
-ieq | Equal 等於,忽略大小寫 |
-ceq | Equal 等於,比較大小寫 |
-ne | Not Equal 不等於,忽略大小寫 |
-ine | Not Equal 不等於,忽略大小寫 |
-cne | Not Equal 不等於,比較大小寫 |
-gt | Great Than 大於,忽略大小寫 |
-igt | Great Than 大於,忽略大小寫 |
-cgt | Great Than 大於,比較大小寫 |
-ge | Great Equal 大於等於,忽略大小寫 |
-ige | Great Equal 大於等於,忽略大小寫 |
-cge | Great Equal 大於等於,比較大小寫 |
-lt | Less Than 小於,忽略大小寫 |
-ilt | Less Than 小於,忽略大小寫 |
-clt | Less Than 小於,比較大小寫 |
-le | Less Equal 小於等於,忽略大小寫 |
-ile | Less Equal 小於等於,忽略大小寫 |
-cle | Less Equal 小於等於,比較大小寫 |
-
仔細觀察可以發現,只要加上 i 就是不區分大小寫;加上 c 就是區分大小寫
-
從範例來理解 -in & -contains
$a = 5 1..3 -contains $a 1..10 -contains $a $a -in 1..3 $a -in 1..10
-
從範例來了解 -is & -isnot
$a = 5 $b = "5" $a.GetType() $b.GetType() $a -is [int] $a -isnot $b.GetType()
-
需要特別注意的特例
$a = 1, 2, $null, 4, $null, 6
$a.GetType()
$a -ne $null
$null -ne $a
"abc" -eq "abc" # Output: True
"abc" -eq "abc", "def" # Output: False
"abc" -ne "def" # Output: True
"abc" -ne "abc" # Output: False
"abc" -ne "abc", "def" # Output: True
"abc", "def" -eq "abc" # Output: abc
"abc", "def" -ne "abc" # Output: def
說明:當集合在運算子左邊時,其結果會是過濾變數值
- 再來一個自訂類別的比較
class MyFileInfoSet {
[String]$File
[Int64]$Size
}
$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$b = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$a -eq $b
上面程式碼雖然透過自訂類別,設定了兩個變數,兩個變數的屬性值雖然都一樣,但這兩個變數是不同的物件, -eq 會認為這不是同一個物件。
所以要讓 -eq 能判斷物件"值" 是否一致,要改用以下程式,讓程式知道使用 -eq 比較時,是要比較兩個變數的值
class MyFileInfoSet : System.IEquatable[Object]{
[String]$File
[Int64]$Size
[bool] Equals([Object] $obj){
return ($this.File -eq $obj.File) -and ($this.Size -eq $obj.Size)
}
}
$c = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$d = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$c -eq $d
我們再來看看兩個類別宣告出來的物件變數的方法有甚麼不同
class MyFileInfoSet {
[String]$File
[Int64]$Size
}
$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$a | Get-Member
class MyFileInfoSet2 : System.IEquatable[Object]{
[String]$File
[Int64]$Size
[bool] Equals([Object] $obj){
return ($this.File -eq $obj.File) -and ($this.Size -eq $obj.Size)
}
}
$c = [MyFileInfoSet2]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$c | Get-Member
($c | Get-Member) | Where-Object { $_.Name -eq "Equals" } | Select-Object -Property Definition
Break、Continue、Return、Exit
Break 中斷迴圈或是 Switch,或是 Trap
-
範例一:
$i=0 $varB = 10,20,30,40 foreach ($val in $varB) { if ($val -eq 30) { break } $i++ } Write-Host "30 was found in array index $i"
-
範例二:中斷指定的迴圈(這是很差的程式習慣,請盡量不要使用)
Remove-Variable * -ErrorAction SilentlyContinue $b = 3 :red while ($true) { :yellow while ($true) { while ($true) { if ($a) {break} if ($b) {break yellow} if ($c) {break red} } Write-Host "中斷最內層迴圈" } Write-Host "中斷 :yellow 迴圈" } Write-Host "中斷 :red 迴圈"
如果有定義 $a,就會中斷最內層迴圈
如果有定義 $b,就會中斷 :yellow 迴圈
如果有定義 $c,就會中斷 :red 迴圈
- 範例三:
function test { trap [DivideByZeroException] { Write-Host 'divide by zero trapped' break } $i = 3 'Before loop' while ($true) { "1 / $i = " + (1 / $i--) } 'After loop' } test
當除數為0的例外被觸發時,印出 “divide by zero trapped”
然後就終止函式
如果沒有使用 Break,就會在發生錯誤之後,繼續執行印出 “After loop”
請不要在迴圈(不包含 ForEach-Object)、Switch、Trap 之外使用 Break!這會目前的 Runspace 被終止!
function test {
"TEST"
break
}
test
"After Test"
當程式執行 test 函式時,輸出 “TEST” 之後,整個程式就被 break 終止了!所以 “After Test” 永遠不會被執行到。
1..10 | ForEach-Object{
If ($_ -eq 3){
Break
}
$_
}
"迴圈之後,繼續執行"
在 ForEach-Object 內使用 Break,也會導致整個程式被終止!
ForEach ($v in 1..10){
If ($v -eq 3){
Break
}
$v
}
"迴圈之後,繼續執行"
但是在 ForEach ($variable in <collection>){} 迴圈卻不會中斷整個程式
0 意見:
張貼留言