РАЗДЕЛ 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