about_Foreach
主題
about_Foreach
簡短描述
描述可用來周遊於項目集合中所有項目的語言命令。
完整描述
Foreach 陳述式 (也稱為 Foreach 迴圈) 是一種語言建構,用以逐項 (反覆) 處理項目集合中
的一連串數值。
最簡單且最常周遊的集合類型是陣列。
Foreach 迴圈內部常會對陣列中的每個項目執行一或多個命令。
語法
Foreach 的語法如下:
foreach ($<項目> in $<集合>){<陳述式清單>}
命令管線外的 Foreach 陳述式 Foreach 陳述式置於括號中的部分代表變數以及所要反覆處理
的集合。Windows PowerShell 會在 Foreach 迴圈執行時自動建立變數 ($<項目>)。每次反覆
處理迴圈之前,會先將此變數設定為集合中的某個值。Foreach 陳述式後面的區塊 {<陳述式
清單>} 包含了要對集合中的每個項目執行的一組命令。
範例
例如,下列 Foreach 迴圈範例將顯示 $letterArray 陣列中的值。
$letterArray = "a","b","c","d"
foreach ($letter in $letterArray)
{
Write-Host $letter
}
此範例使用字串值 "a"、"b"、"c" 和 "d" 建立並初始化 $letterArray 陣列。
Foreach 陳述式第一次執行時,會將 $letter 變數設定為等於 $letterArray ("a")
中的第一個項目, 然後再使用 Write-Host Cmdlet 來顯示字母 a。下一次通過迴圈
時,$letter 會設定為 "b",以此類推。直到 Foreach 迴圈顯示字母 d 之後,Windows
PowerShell 隨即結束迴圈。
在 Windows PowerShell 命令提示字元輸入時,整個 Foreach 陳述式必須寫成一行才能執
行命令。如果是將命令放在 .ps1 指令檔中,則不需要以單一行顯示整個 Foreach 陳
述式。
Foreach 陳述式也能與傳回項目集合的 Cmdlet 搭配使用。在下列範例中,Foreach 陳述
式將逐項處理 Get-ChildItem Cmdlet 所傳回的項目清單。
foreach ($file in Get-ChildItem)
{
Write-Host $file
}
您可以修改上述範例,使用 If 陳述式限制傳回的結果。在下列範例中,Foreach 陳述式
不僅執行與上述範例相同的迴圈處理作業,還加入 If 陳述式將結果限制為大小超過 100
KB 的檔案:
foreach ($file in Get-ChildItem)
{
if ($file.length -gt 100k)
{
Write-Host $file
}
}
在此範例中,Foreach 迴圈會利用 $file 變數的屬性執行比較運算 ($file.length -gt 100k)。
$file 變數包含了 Get-ChildItem Cmdlet 所傳回物件的全部屬性。因此,您還能
傳回檔名以外的其他資訊。在下列範例中,Windows PowerShell 於陳述式清單內傳回長
度和上次存取時間:
foreach ($file in Get-ChildItem)
{
if ($file.length -gt 100k)
{
Write-Host $file
Write-Host $file.length
Write-Host $file.lastaccesstime
}
}
此範例中沒有在陳述式清單中執行單一命令的限制。
您也可以在 Foreach 迴圈外使用變數,而在迴圈內遞增其值。下列範例會計算大小超
過 100 KB 的檔案:
$i = 0
foreach ($file in Get-ChildItem)
{
if ($file.length -gt 100k)
{
Write-Host $file "檔案大小:" ($file.length /
1024).ToString("F0") KB
$i = $i + 1
}
}
if ($i -ne 0)
{
Write-Host
Write-Host $i " 個檔案在目前目錄中超過 100 KB。"}
else
{
Write-Host "目前目錄中沒有大於 100 KB 的檔案。"
}
在前述範例中,在迴圈外將 $i 變數設為 0,且迴圈內每找到一個大於 100 KB 的檔案時
便遞增變數值。結束迴圈後,If 陳述式會評估 $i 的值以顯示所有超過 100 KB 的檔案
數目, 或顯示訊息表示找不到大於 100 KB 的檔案。
上述範例也示範如何將檔案長度結果格式化:
($file.length / 1024).ToString("F0")
值先除以 1,024 而從位元組改為顯示以 KB 為單位的結果,然後使用固定小數點格式指
定元移除結果中的小數點。當中的 0 係指示格式指定元不應顯示任何小數位數。
命令管線內的 Foreach 陳述式 每當 Foreach 出現在命令管線內,Windows PowerShell 便會
使用 foreach 別名藉以呼叫 ForEach-Object 命令。若在命令管線內使用 foreach 別名,
就不必加上 Foreach 陳述式應有的 ($<項目> in $<集合>) 語法。這是因為管線內的上一個命
令會提供此資訊。用於命令管線內的 foreach 別名使用下列語法:
<命令> | foreach {<命令區塊>}
例如,下列命令管線內的 Foreach 迴圈將顯示工作組 (記憶體使用量) 大於 20 MB 的所
有處理序。Windows PowerShell 會將 Get-Process 命令的輸出傳送給 foreach
別名。而在 foreach 別名的命令區塊內,$_.WS 變數包含了由 Get-Process Cmdlet
傳來的 WS (工作組) 屬性的值 (宣告的 $_ 部分是 Windows Script Host [WSH]
自動變數,WS 部分則是屬性)。接著 If 陳述式使用條件陳述式判斷工作組是否大於
20 MB (20,000,000 位元組)。如果是,便會顯示處理序的名稱 (儲存於 $_.name 變數)
以及工作組的大小 (以 MB 為單位)。
若所有的處理序工作組都不超過 20 MB,就不會顯示任何資訊。
Write-Host "工作組大於 20 MB 的處理序" Get-Process | foreach {
if ($_.WS -gt 20m)
{
Write-Host $_.name ": "
($_.WS/1m).ToString("F0") MB -Separator ""
}
}
foreach 別名也支援起始命令區塊、中間命令區塊以及結尾命令區塊。起始與結尾命令區
塊僅執行一次,中間命令區塊則是在 Foreach 迴圈每次逐項處理集合或陣列時都會執行。
在命令管線內使用,且包含起始、中間與結尾命令區塊之 foreach 別名的語法如下:
<命令> | foreach {<起始命令區塊>}{<中間命令區塊>}{<結尾命令區塊>}
下列範例示範起始、中間與結尾命令區塊的用法。
Get-ChildItem | foreach {
$fileCount = $directoryCount = 0}{
if ($_.PsIsContainer) {$directoryCount++} else
{$fileCount++}}{ "$directoryCount 個目錄和 $fileCount 個檔案"}
起始區塊會建立兩個變數並將其初始化為 0:
{$fileCount = $directoryCount = 0}
中間區塊會評估 Get-ChildItem 所傳回的每個項目是目錄或檔案:
{if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}}
如果傳回的項目是目錄,$directoryCount 變數會以 1 遞增。如果該項目不是目錄,
$fileCount 變數會以 1 遞增。結束區塊會在中間區塊完成其迴圈作業之後執行,然
後再傳回作業的結果。
{"$directoryCount 個目錄和 $fileCount 個檔案"}
您可以使用起始、中間與結尾命令區塊結構以及管線運算子來改寫稍早的範例,找出大小
超過 100 KB 的檔案,如下所示:
Get-ChildItem | foreach{
$i = 0}{
if ($_.length -gt 100k)
{
Write-Host $_.name "檔案大小:" ($_.length /
1024).ToString("F0") KB
$i++
}
}{
if ($i -ne 0)
{
Write-Host
Write-Host "$i 個檔案在目前目錄中超過 100 KB。"
}
else
{
Write-Host "目前目錄中沒有大於 100 KB 的檔案。"}
}
請參閱
about_Automatic_Variables
about_If
Foreach-Object