about_Foreach
Краткое описание
Описывает языковую команду, с помощью которой можно просматривать все элементы в коллекции элементов.
Подробное описание
Оператор foreach
— это языковая конструкция для перебора набора значений в коллекции.
Самый простой и типичный тип коллекции для просмотра — массив.
В цикле foreach
обычно выполняется одна или несколько команд для каждого элемента в массиве.
Синтаксис
Ниже показан foreach
синтаксис:
foreach ($<item> in $<collection>){<statement list>}
foreach
Часть оператора внутри круглых скобок представляет переменную и коллекцию для итерации. PowerShell автоматически создает переменную $<item>
при выполнении foreach
цикла. В начале каждой итерации foreach
задает для переменной item следующее значение в коллекции. Блок {<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
для отображения значения. При следующем прохождении цикла $letter
задается значение b
. Шаблон повторяется для каждого элемента в массиве.
Операторы также можно использовать foreach
с командлетами, возвращающими коллекцию элементов. В следующем примере инструкция выполняет пошаговое выполнение списка элементов, foreach
возвращаемых командлетом Get-ChildItem
.
foreach ($file in Get-ChildItem)
{
Write-Host $file
}
Вы можете уточнить пример с помощью if
оператора , чтобы ограничить возвращаемые результаты. В следующем примере if
инструкция ограничивает результаты файлами, размер которых превышает 100 килобайт (КБ):
foreach ($file in Get-ChildItem)
{
if ($file.Length -gt 100KB)
{
Write-Host $file
}
}
В этом примере foreach
цикл использует свойство переменной $file
для выполнения операции сравнения ($file.length -gt 100KB
). Переменная $file
имеет все свойства объекта , возвращаемого Get-ChildItem
объектом .
В следующем примере скрипт отображает длину и время последнего доступа в списке инструкций:
foreach ($file in Get-ChildItem)
{
if ($file.Length -gt 100KB)
{
Write-Host $file
Write-Host $file.Length
Write-Host $file.LastAccessTime
}
}
Можно также использовать переменные извне foreach
цикла. В следующем примере подсчитывается количество файлов размером более 100 КБ:
$i = 0
foreach ($file in Get-ChildItem) {
if ($file.length -gt 100KB) {
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 100KB in the current directory.'
}
else {
Write-Host 'No files greater than 100KB in the current directory.'
}
В предыдущем примере $i
начинается со значения 0
вне цикла .
$i
Затем увеличивается внутри цикла для каждого файла размером более 100 КБ. Когда цикл завершается, if
инструкция оценивает значение $i
, чтобы отобразить количество файлов свыше 100 КБ.
В предыдущем примере также показано, как форматировать результаты по длине файла:
($file.length / 1024).ToString('F0')
Значение делится на 1024 для отображения результатов в килобайтах, а не в байтах, а затем полученное значение форматируется с помощью описателя формата с фиксированной запятой, чтобы удалить все десятичные значения из результата. Указывает 0
, что описатель формата не отображает десятичные разряды.
Следующая функция анализирует скрипты и модули сценариев PowerShell и возвращает расположение функций, содержащихся в ней. В примере показано, как использовать MoveNext
метод и Current
свойство переменной $foreach
внутри блока скрипта foreach
.
Дополнительные сведения см. в разделе Использование перечислителей.
function Get-FunctionPosition {
[CmdletBinding()]
[OutputType('FunctionPosition')]
param(
[Parameter(Position = 0, Mandatory,
ValueFromPipeline, ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[Alias('PSPath')]
[System.String[]]
$Path
)
process {
try {
$filesToProcess = if ($_ -is [System.IO.FileSystemInfo]) {
$_
} else {
Get-Item -Path $Path
}
$parser = [System.Management.Automation.Language.Parser]
foreach ($item in $filesToProcess) {
if ($item.PSIsContainer -or
$item.Extension -notin @('.ps1', '.psm1')) {
continue
}
$tokens = $errors = $null
$ast = $parser::ParseFile($item.FullName, ([ref]$tokens),
([ref]$errors))
if ($errors) {
$msg = "File '{0}' has {1} parser errors." -f $item.FullName,
$errors.Count
Write-Warning $msg
}
:tokenLoop foreach ($token in $tokens) {
if ($token.Kind -ne 'Function') {
continue
}
$position = $token.Extent.StartLineNumber
do {
if (-not $foreach.MoveNext()) {
break tokenLoop
}
$token = $foreach.Current
} until ($token.Kind -in @('Generic', 'Identifier'))
$functionPosition = [pscustomobject]@{
Name = $token.Text
LineNumber = $position
Path = $item.FullName
}
$addMemberSplat = @{
InputObject = $functionPosition
TypeName = 'FunctionPosition'
PassThru = $true
}
Add-Member @addMemberSplat
}
}
}
catch {
throw
}
}
}