about_Foreach
主题
about_Foreach
简短说明
说明可用于遍历项集合中的所有项的一种语言命令。
详细说明
Foreach 语句(也称为 Foreach 循环)是一种用于逐一遍历(循环访问)项集合中一系列值的语言
结构。
可遍历的最简单、最典型的集合类型是数组。在 Foreach 循环中,经常会针对数组中的
每一项运行一个或多个命令。
语法
下面显示了 Foreach 语法:
foreach ($<item> in $<collection>){<statement list>}
命令管道之外的 Foreach 语句 Foreach 语句中括在括号中的部分表示一个变量和一个要循环访问的集
合。Windows PowerShell 在运行 Foreach 循环时自动创建该变量 ($<item>)。在每次迭代通过循
环之前,该变量将设置为集合中的值。Foreach 语句后面的语句块 {<statement list>} 包含一组要
针对集合中的各项执行的命令。
示例
例如,以下示例中的 Foreach 循环显示了 $letterArray 数组中的值。
$letterArray = "a","b","c","d"
foreach ($letter in $letterArray)
{
Write-Host $letter
}
在此示例中,将创建 $letterArray 数组,并使用字符串值"a"、"b"、"c"和"d"对其进行初
始化。Foreach 语句第一次运行时,将 $letter 变量设置为与 $letterArray 中的第一项
("a")相等的值。然后,该语句使用 Write-Host cmdlet 显示字母 a。下一次通过循环时,
$letter 被设置为"b",依此类推。在 Foreach 循环显示字母 d 之后,Windows PowerShell
退出循环。
要在 Windows PowerShell 命令提示符下将 Foreach 语句作为命令运行,则整个 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 size:" ($file.length /
1024).ToString("F0") KB
$i = $i + 1
}
}
if ($i -ne 0)
{
Write-Host
Write-Host $i " file(s) over 100 KB in the current
directory."}
else
{
Write-Host "No files greater than 100 KB in the current
directory."
}
在上一示例中,在循环外将 $i 变量设置为 0,并在每找到一个大于 100 KB 的文件时在循环内将该
变量递增 1。退出循环时,If 语句对 $i 的值进行计算,以显示超过 100 KB 的所有文件的计数。
或者,该语句将显示一条消息,表明没有找到超过 100 KB 的文件。
上一示例还演示了设置文件长度结果格式的方式:
($file.length / 1024).ToString("F0")
该值除以 1024 即可以千字节(而不是字节)为单位显示结果,随后使用固定点格式说明符对计算得
到的值进行格式设置,以删除结果中的所有小数值。"0"将使格式说明符不显示小数位。
命令管道之内的 Foreach 语句
当 Foreach 出现在命令管道中时,Windows PowerShell 将使用 foreach 别名调用 ForEach-Object 命令。
在命令管道中使用 foreach 别名时,无需像在 Foreach 语句中那样包含 ($<item> in $<collection>) 语法。
这是因为管道中的前一命令已提供此信息。在命令管道中使用的 foreach 别名的语法如下:
<command> | foreach {<command_block>}
例如,以下命令管道中的 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 变量中的该进程的名称,并以兆字节为单位显示工作集大小。
如果不存在超过 20 MB 的进程工作集,则不显示任何内容。
Write-Host "Processes with working-sets greater than 20 MB" Get-
Process | foreach {
if ($_.WS -gt 20m)
{
Write-Host $_.name ": "
($_.WS/1m).ToString("F0") MB -Separator ""
}
}
foreach 别名还支持起始命令块、中间命令块和结尾命令块。起始命令块和结尾命令块只运行一
次,而中间命令块在每次 Foreach 循环访问一次集合或数组时都运行一次。
Foreach 别名在具有起始、中间和结尾命令块组的命令管道中使用时的语法为:
<command> | foreach {<beginning command_block>}{<middle
command_block>}{<ending command_block>}
以下示例演示了起始、中间和结尾命令块的用法。
Get-ChildItem | foreach {
$fileCount = $directoryCount = 0}{
if ($_.PsIsContainer) {$directoryCount++} else
{$fileCount++}}{ "$directoryCount directories and $fileCount files"}
起始命令块创建两个变量,并将它们初始化为 0:
{$fileCount = $directoryCount = 0}
中间命令块计算由 Get-ChildItem 返回的每项是目录还是文件:
{if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}}
如果返回的项是目录,则 $directoryCount 变量递增 1。如果该项不是目录,则 $fileCount
变量递增 1。结尾命令块在中间命令块完成循环操作之后运行,返回计算结果:
{"$directoryCount directories and $fileCount files"}
通过使用起始、中间和结尾命令块结构及管道运算符,可以重新编写前面的示例,以查找大于
100 KB 的任何文件,如下所示:
Get-ChildItem | foreach{
$i = 0}{
if ($_.length -gt 100k)
{
Write-Host $_.name "file size:" ($_.length /
1024).ToString("F0") KB
$i++
}
}{
if ($i -ne 0)
{
Write-Host
Write-Host "$i file(s) over 100 KB in the current
directory."
}
else
{
Write-Host "No files greater than 100 KB in the current
directory."}
}
另请参阅
about_Automatic_Variables
about_If
Foreach-Object