РАЗДЕЛ
about_Foreach
КРАТКОЕ ОПИСАНИЕ
Описывает команду языка, позволяющую перебрать все элементы в
коллекции.
ПОЛНОЕ ОПИСАНИЕ
Инструкция Foreach (называемая также циклом Foreach) является языковой
конструкцией для пошагового перемещения (итерации) по последовательности
значений в коллекции элементов.
Самым простым и наиболее часто используемым типом коллекции, по
которой производится перемещение, является массив. Обычно в цикле
Foreach одна или несколько команд выполняются на каждом элементе массива.
Синтаксис
Ниже показан синтаксис инструкции Foreach:
foreach ($<элемент> in $<коллекция>){<список_инструкций>}
Инструкция Foreach за пределами конвейера команд В заключаемой в круглые
скобки части инструкции Foreach указываются переменная и коллекция для перебора.
При выполнении цикла Foreach среда Windows PowerShell автоматически создает переменную
($<элемент>). Перед каждой итерацией в цикле переменной присваивается значение в коллекции.
Блок за инструкцией Foreach {<список_инструкций>} содержит набор команд, выполняемых на
каждом элементе коллекции.
Примеры
Например, цикл Foreach в следующем примере отображает значения
в массиве $letterArray.
$letterArray = "a","b","c","d"
foreach ($letter in $letterArray)
{
Write-Host $letter
}
В этом примере создается массив $letterArray, который затем
инициализируется строковыми значениями "a", "b", "c" и "d". При первом
выполнении инструкции Foreach переменная $letter устанавливается
равной первому элементу в массиве $letterArray ("a"). Затем буква "a"
отображается с помощью командлета Write-Host. При следующей итерации цикла
переменной $letter присваивается значение "b" и т. д. После того как цикл
Foreach отобразит букву "d", Windows PowerShell выходит из цикла.
Инструкция Foreach должна представляться в одной строке
целиком, чтобы она выполнялась как команда в командной строке
Windows PowerShell. Инструкция Foreach не обязательно должна
представляться в одной строке целиком, если команда помещается
в файл скрипта PS1.
Инструкции Foreach могут также использоваться совместно с
командлетами, возвращающими коллекции элементов. В следующем примере
инструкция Foreach выполняет перебор элементов списка, возвращаемого
командлетом Get-ChildItem.
foreach ($file in Get-ChildItem)
{
Write-Host $file
}
Пример может быть усовершенствован при помощи инструкции If для
ограничения возвращаемых результатов. В следующем примере инструкция
Foreach выполняет те же операции в цикле, что и в предыдущем примере,
но здесь добавлена инструкция If, ограничивающая результаты файлами,
размер которых превышает 100 килобайт (КБ).
foreach ($file in Get-ChildItem)
{
if ($file.length -gt 100k)
{
Write-Host $file
}
}
В этом примере цикл Foreach использует свойство переменной $file для
выполнения операции сравнения ($file.length -gt 100k). Переменная
$file содержит все свойства в объекте, возвращаемом командлетом
Get-ChildItem. Поэтому может возвращаться не только имя файла.
В следующем примере 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 КБ:
$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 КБ. При выходе из цикла инструкция
If вычисляет значение переменной $i для отображения количества всех
файлов размером более 100 КБ. Либо отображается сообщение о том,
что ни одного файла размером более 100 КБ не найдено.
Предыдущий пример также демонстрирует, как форматировать
результаты для длины:
($file.length / 1024).ToString("F0")
Значение делится на 1024, чтобы показать результаты в
килобайтах, а не в байтах. Полученное значение далее
форматируется при помощи спецификатора формата с фиксированной
запятой для удаления из результата дробной части. Значение 0
спецификатора формата указывает, что дробная часть отображаться
не должна.
Инструкция Foreach внутри конвейера команд Когда инструкция Foreach
используется в конвейере команд, Windows PowerShell использует псевдоним
foreach, вызывающий команду ForEach-Object. При использовании псевдонима
foreach в конвейере команд не используется синтаксическая конструкция
($<элемент> in $<коллекция>), как это делается с инструкцией Foreach.
Это является следствием того, что эти сведения предоставляет предыдущая
команда в конвейере. Синтаксис псевдонима foreach, применяемого в
конвейере команд, выглядит следующим образом:
<команда> | foreach {<блок_команд>}
Например, цикл Foreach в следующем конвейере команд отображает все
процессы, рабочий набор (использование памяти) которых превышает 20
мегабайт (МБ). Оболочка Windows PowerShell передает выходные данные
команды Get-Process по конвейеру псевдониму foreach. Внутри блока
команд псевдонима foreach переменная $_.WS содержит значение свойства
WS (рабочего набора), передаваемое ей командлетом Get-Process.
(Часть $_ объявления является автоматической переменной WSH, а часть
WS является свойством.) Инструкция If использует условное выражение для
определения того, превышает ли рабочий набор 20 МБ (20 000 000 байт).
Если превышает, то отображаются имя процесса, хранящееся в переменной
$_.name, и размер рабочего набора в мегабайтах. При отсутствии рабочего
набора процесса, размер которого превышает 20 МБ, ничего не отображается.
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, используемого в конвейере команд с
начальным, средним и конечным блоками команд выглядит следующим образом:
<команда> | foreach {<начальный_блок_команд>}
{<средний_блок_команд>}{<конечный_блок_команд>}
В следующем примере демонстрируется использование начального,
среднего и конечного блоков команд.
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. Если элемент не является
каталогом, на 1 увеличивается значение переменной $fileCount.
Конечный блок выполняется после того, как средний блок завершит
цикл и вернет результат операции:
{"$directoryCount directories and $fileCount files"}
При помощи структуры начального, среднего и конечного блоков и
оператора конвейера можно переписать приведенный выше пример
поиска файлов размером более 100 КБ следующим образом:
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