循環是控制流中的重要部分,容許在條件知足的狀況下重複執行腳本代碼塊。
簡單循環語句while
當簡單while循環中的條件表達式成立時,將重複的執行腳本塊,其通常格式以下:
while (<condition>)
{
<action block>
}
下例等待notepad.exe進程退出:
PS C:\> while (Get-Process notepad -ErrorAction SilentlyContinue){
>> Write-Host "Waiting for notepad to exit"
>> sleep 1
>> }
>>
Waiting for notepad to exit
Waiting for notepad to exit
Waiting for notepad to exit
Get-Process notepad -ErrorAction SilentlyContinue語句是反覆執行的,並會被轉換爲布爾類型的值。若是未發現進程,Get-Process將會拋出一個異常,因此傳遞-ErrorAction SilentlyContinue參數執行容錯處理。若是未發現進程僅僅返回一個$null值,則該值會被轉換爲$false並退出循環。爲了避免讓CPU老是執行無謂。循環而消耗資源,在每一個循環過程當中調用了sleep命令,在每次循環過程當中執行一秒鐘的任務後掛起。
若是條件表達式初始化爲$false,while循環體將永遠不會被執行。爲了讓循環體至少執行一次,可使用do-while形式,如:
PS C:\> $i=5
PS C:\> do{
>> Write-Host 'incermenting $i'
>> $i++
>> }while($i -le 1)
>>
incermenting $i
在使用do-while語句時,不管條件成立與否,循環體老是要被執行一次。
該語句肯定條件使循環重複執行,直到條件成立,如:
PS C:\> $i=5
PS C:\> do{
>> Write-Host 'incermenting $i'
>> $i++
>> }while($i -le 1)
>>
incermenting $i
PS C:\> $i=0;
PS C:\> do{
>> Write-Host "`$i=$i"
>> $i++
>> }until ($i -ge 3)
>>
$i=0
$i=1
$i=2
下例中的do-while和do-until循環僅條件不一樣:
PS C:\> $i=5
PS C:\> do{
>> Write-Host 'incermenting $i'
>> $i++
>> }while($i -le 1)
>>
incermenting $i
PS C:\> $i=0;
PS C:\> do{
>> Write-Host "`$i=$i"
>> $i++
>> }while (-not($i -ge 3))
>>
$i=0
$i=1
$i=2
循環和計數器
通常循環包括初始化一個變量做爲計數器,而且在每一個循環體中修改該計數器,直到知足退出條件。這種形式的循環出即for…loop結構,其通常格式以下:
for(<initializer>;<exit condition>;<step action>)
{
<action>
}
這種循環經過初始化計數器,每次循環的過程當中遞增或者遞減該計數器,直到計數器達到退出要求。下例使用for循環重寫前一節的while循環:
PS C:\> for($i=0;$i -lt 3;$i++){
>> Write-Host "`$i=$i"
>> }
>>
$i=0
$i=1
$i=2
for循環比while更爲緊湊,能夠將其做爲while的超集。初始化和步進值對於for循環爲可選,若是忽略這些參數,for循環的做用與while相似,如:
PS C:\> $i=0;
PS C:\> for(;$i -lt 3;){
>> Write-Host "`$i=$i"
>> $i++
>> }
>>
$i=0
$i=1
$i=2
注意,若是在for循環的條件中省略計數器的初始化和步進表達式,則必須在括號中添加循環退出條件。
遍歷集合的循環語句for each Loop
不少狀況下須要遍歷集合,以操做每一個成員,下例使用for循環來達到這個目的:
PS C:\>$items=2,3,4
PS C:\>for($i=0;$i –lt $items.Length;$i++){
>>$item=$items[$i]
>>Write-Host $item
>>}
>>
2
3
4
其中$i變量包含當前項的索引值,$i –lt $items.Length是退出條件。遞增語句做爲循環的步進值,$item變量使用當前項初始化。PowerShell提供了更爲便利的foreach循環,其通常格式以下:
foreach($item in $collection)
{
<action>
}
注意foreach須要提供包含當前項的變量名及要遍歷的集合,即索引的初始化、退出條件,以及索引遞增已經隱藏到其中。下例使用foreach優化前面的實例:
PS C:\>$items=2,3,4
PS C:\>foreach ($item in $items){
>> Write-Host $item
>>}
>>
2
3
4
foreach是PowerShell的保留字,同時也是ForEach-Object的別名。PowerShell的解釋引擎是會根據語境檢測出foreach是做爲循環或者ForEach-Object建立管道對象。
控制循環執行語句break和continue
並非全部的循環都須要嚴格的退出條件,若是要檢測錯誤或者只是想優化程序,可能但願腳本循環強制退出。強制退出循環使用break語句,下例在當前目錄中獲取第1個有.log後綴的文件後退出:
PS C:\>foreach ($file in dir){
>>if($file.Name –like "*.log"){
>>Write-Host $fiile.Name
>>break
>> }
>>}
>>
test.log
若是反覆遍歷一個集合並操做其中的大多數對象,可使用continue語句。break所在的程序段的條件知足的狀況下將會退出整個循環,而continue語句塊的條件成立時將會跳過當前循環,繼續下一個循環。下例說明如何使用continue語句在遍歷集合的過程當中跳過偶數輸出全部的奇數:
PS C:\>foreach ($item in 1..5){
>> if ($item %2 –eq 0){
>> continue
>> }
>>Write-Host $item
>>}
1
3
5
在上例中使用取模(%)運算符來判斷一個數是奇數仍是偶數,偶數除以2餘數爲零,即模2。
break和continue能夠被賦予一個使其退出或者轉向循環的其餘迭代的循環標記,對嵌套循環很是有用。下例爲針對兩個嵌套的foreach循環:
PS C:\>foreach ($outerItem in 1..3){
>> Write-Host "OuterItem:$outerItem"
>> foreach($innerItem in 1..3){
>> Write-Host "InnerItem:$innerItem"
>> break;
>> }
>>Write-Host $item
>>}
>>
OuterItem:1
InnerItem:1
OuterItem:2
InnerItem:1
OuterItem:3
InnerItem:1
內部循環在外部循環反覆執行過程當中只執行一遍,這是由於break語句在每次執行第1個Write-Host語句後終止循環。若是要終止外部循環,而不是內部循環,則能夠在外部循環中增長break語句;
PS C:\>:OuterLoop foreach ($outerItem in 1..3){
>> Write-Host "OuterItem:$outerItem"
>> foreach($innerItem in 1..3){
>> Write-Host "InnerItem:$innerItem"
>> break OuterLoop;
>> }
>>Write-Host $item
>>}
>>
OuterItem:1
InnerItem:1
這樣內外兩層循環均只執行一次,內部的break語句終止外部的循環,有效地終止了循環:
PS C:\>:OuterLoop foreach ($outerItem in 1..3){
>> Write-Host "OuterItem:$outerItem"
>> foreach($innerItem in 1..3){
>> Write-Host "InnerItem:$innerItem"
>> break OuterLoop;
>> }
>>Write-Host $item
>>}
>>
OuterItem:1
InnerItem:1
OuterItem:2
InnerItem:1
OuterItem:3
InnerItem:1
執行結果和本節第1個例子相同,由於continue在終止內部循環的同時開始執行外部循環。
總 結
若是說算法是程序的靈魂,那麼控制流就是程序運行的骨架。控制流直接決定了程序運行路徑,控制流的內容將會貫穿整個PowerShell學習的全過程,本文主要講解了循環語句,包括while,for each loop,break和continue,掌握了這部份內容以後讀者就能夠寫出在平常工做中用到該功能的命令。
做者: 付海軍
出處:
http://fuhj02.blog.51cto.com 版權:本文版權歸做者和51cto共有 轉載:歡迎轉載,爲了保存做者的創做熱情,請按要求【轉載】,謝謝 要求:未經做者贊成,必須保留此段聲明;必須在文章中給出原文鏈接;不然必究法律責任 我的網站: http://txj.shell.tor.hu/