about_For
Краткое описание
Описывает команду языка, используемую для выполнения инструкций на основе условного теста.
Подробное описание
Оператор For
(также известный как For
цикл) — это конструкция языка, которую можно использовать для создания цикла, выполняющего команды в блоке команд, в то время как указанное условие вычисляется $true
.
Обычное For
использование цикла заключается в итерации массива значений и работе с подмножеством этих значений. В большинстве случаев, если требуется выполнить итерацию всех значений в массиве, рекомендуется использовать инструкцию Foreach
.
Синтаксис
Ниже показан синтаксис инструкции For
.
for (<Init>; <Condition>; <Repeat>)
{
<Statement list>
}
Заполнитель Init представляет одну или несколько команд, выполняемых перед началом цикла. Обычно используется часть инструкции Init для создания и инициализации переменной с начальным значением.
Затем эта переменная будет основой для проверки условия в следующей части инструкции For
.
Заполнитель условия представляет часть инструкцииFor
, разрешающей $true
$false
логическое значение. PowerShell оценивает условие при For
каждом запуске цикла. Если оператор имеет значение $true
, команды в выполнении блока команд и инструкция вычисляется снова. Если условие по-прежнему$true
, команды в списке инструкций выполняются снова.
Цикл повторяется до тех пор, пока условие не станет $false
.
Заполнитель "Повторять " представляет одну или несколько команд, разделенных запятыми, которые выполняются при каждом повторе цикла. Как правило, это используется для изменения переменной, тестируемой внутри части инструкции Condition .
Заполнитель списка инструкций представляет набор одной или нескольких команд, выполняемых каждый раз при вводе или повторе цикла. Содержимое списка инструкций окружено фигурными скобками.
Поддержка нескольких операций
Следующие синтаксисы поддерживаются для нескольких операций назначения в инструкции Init :
# Comma separated assignment expressions enclosed in parentheses.
for (($i = 0), ($j = 0); $i -lt 10; $i++)
{
"`$i:$i"
"`$j:$j"
}
# Sub-expression using the semicolon to separate statements.
for ($($i = 0;$j = 0); $i -lt 10; $i++)
{
"`$i:$i"
"`$j:$j"
}
Следующие синтаксисы поддерживаются для нескольких операций назначения в инструкции Repeat :
# Comma separated assignment expressions.
for (($i = 0), ($j = 0); $i -lt 10; $i++, $j++)
{
"`$i:$i"
"`$j:$j"
}
# Comma separated assignment expressions enclosed in parentheses.
for (($i = 0), ($j = 0); $i -lt 10; ($i++), ($j++))
{
"`$i:$i"
"`$j:$j"
}
# Sub-expression using the semicolon to separate statements.
for ($($i = 0;$j = 0); $i -lt 10; $($i++;$j++))
{
"`$i:$i"
"`$j:$j"
}
Примечание.
Операции, отличные от предварительных или постовых добавок, могут не работать со всеми синтаксисами.
Для нескольких условий используются логические операторы, как показано в следующем примере.
for (($i = 0), ($j = 0); $i -lt 10 -and $j -lt 10; $i++,$j++)
{
"`$i:$i"
"`$j:$j"
}
Дополнительные сведения см. в about_Logical_Operators.
Примеры синтаксиса
Как минимум, For
оператор требует круглых скобок вокруг инструкции Init, Condition и Repeat части инструкции и команды, окруженной фигурными скобками в списке инструкций.
Обратите внимание, что предстоящие примеры намеренно показывают код за пределами инструкции For
. В последующих примерах код интегрируется в инструкцию For
.
Например, следующая For
инструкция постоянно отображает значение переменной $i
до тех пор, пока вы не будете вручную выйти из команды, нажав клавиши CTRL+C.
$i = 1
for (;;)
{
Write-Host $i
}
Дополнительные команды можно добавить в список инструкций, чтобы значение $i
увеличивается на 1 при каждом запуске цикла, как показано в следующем примере.
for (;;)
{
$i++; Write-Host $i
}
Пока команда не завершится, нажав клавиши CTRL+C, эта инструкция будет постоянно отображать значение переменной $i
, так как она увеличивается на 1 при каждом запуске цикла.
Вместо того чтобы изменить значение переменной в списке инструкций, For
можно использовать часть инструкции Repeat , For
как показано ниже.
$i=1
for (;;$i++)
{
Write-Host $i
}
Эта инструкция по-прежнему будет повторяться неограниченно до тех пор, пока не завершите выполнение команды, нажав клавиши CTRL+C.
Вы можете завершить For
цикл с помощью условия. Условие можно поместить с помощью части условия инструкцииFor
. Цикл For
завершается, когда условие вычисляется $false
.
В следующем примере цикл выполняется в For
то время как значение $i
меньше или равно 10.
$i=1
for(;$i -le 10;$i++)
{
Write-Host $i
}
Вместо создания и инициализации переменной за пределами For
инструкции эту задачу можно выполнить внутри For
цикла с помощью части инструкции For
Init.
for($i=1; $i -le 10; $i++){Write-Host $i}
Вы можете использовать возвращаемую каретки вместо запятой для разделителя инструкции For
Init, Condition и Repeat. В следующем примере показано, что используется этот альтернативный For
синтаксис.
for ($i = 0
$i -lt 10
$i++){
$i
}
Эта альтернативная форма инструкции работает в файлах For
скриптов PowerShell и в командной строке PowerShell. Однако при вводе интерактивных команд в командной строке проще использовать For
синтаксис инструкции с запятой.
Цикл For
является более гибким, чем Foreach
цикл, так как позволяет увеличивать значения в массиве или коллекции с помощью шаблонов. В следующем примере $i
переменная увеличивается на 2 в части For
инструкции Repeat.
for ($i = 0; $i -le 20; $i += 2)
{
Write-Host $i
}
Цикл For
также можно записать в одной строке, как показано в следующем примере.
for ($i = 0; $i -lt 10; $i++) { Write-Host $i }
Функциональный пример
В следующем примере показано, как использовать For
цикл для итерации по массиву файлов и переименовать их. Файлы в папке work_items
имеют идентификатор рабочего элемента в качестве имени файла. Цикл выполняет итерацию по файлам, чтобы убедиться, что номер идентификатора равен нулю до пяти цифр.
Во-первых, код извлекает список файлов данных рабочих элементов. Они все JSON-файлы, использующие формат <work-item-type>-<work-item-number>
для их имени.
С помощью объектов сведений о файле, сохраненных в переменной $fileList
, их можно отсортировать по имени и увидеть, что при группировке элементов по типу порядок элементов по идентификатору непредвиден.
$fileList = Get-ChildItem -Path ./work_items
$fileList | Sort-Object -Descending -Property Name
bug-219.json
bug-41.json
bug-500.json
bug-697.json
bug-819.json
bug-840.json
feat-176.json
feat-367.json
feat-373.json
feat-434.json
feat-676.json
feat-690.json
feat-880.json
feat-944.json
maint-103.json
maint-367.json
maint-454.json
maint-49.json
maint-562.json
maint-579.json
Чтобы убедиться, что рабочие элементы можно отсортировать буквенно,номера рабочих элементов должны быть отсчитываются от нуля.
Код делает это путем первого поиска рабочего элемента с самым длинным числовым суффиксом. Он цикличен по файлам с помощью for
цикла, используя индекс для доступа к каждому файлу в массиве. Он сравнивает каждое имя файла с шаблоном регулярного выражения, чтобы извлечь номер рабочего элемента в виде строки вместо целого числа. Затем он сравнивает длину номеров рабочих элементов, чтобы найти самое длинное число.
# Default the longest numeral count to 1, since it can't be smaller.
$longestNumeralCount = 1
# Regular expression to find the numerals in the filename - use a template
# to simplify updating the pattern as needed.
$patternTemplate = '-(?<WorkItemNumber>{{{0},{1}}})\.json'
$pattern = $patternTemplate -f $longestNumeralCount
# Iterate, checking the length of the work item number as a string.
for (
$i = 0 # Start at zero for first array item.
$i -lt $fileList.Count # Stop on the last item in the array.
$i++ # Increment by one to step through the array.
) {
if ($fileList[$i].Name -match $pattern) {
$numeralCount = $Matches.WorkItemNumber.Length
if ($numeralCount -gt $longestNumeralCount) {
# Count is higher, check against it for remaining items.
$longestNumeralCount = $numeralCount
# Update the pattern to speed up the search, ignoring items
# with a smaller numeral count using pattern matching.
$pattern = $patternTemplate -f $longestNumeralCount
}
}
}
Теперь, когда вы знаете максимальное число рабочих элементов, вы можете циклировать файлы, чтобы переименовать их по мере необходимости. Следующий фрагмент кода снова выполняет итерацию по списку файлов, забив их по мере необходимости. Он использует другой шаблон регулярного выражения для обработки только файлов с числовым числом меньше максимального.
# Regular expression to find the numerals in the filename, but only if the
# numeral count is smaller than the longest numeral count.
$pattern = $patternTemplate -f 1, ($longestNumeralCount - 1)
for (
$i = 0 # Start at zero for first array item.
$i -lt $fileList.Count # Stop on the last item in the array.
$i++ # Increment by one to step through the array.
) {
# Get the file from the array to process
$file = $fileList[$i]
# If the file doesn't need to be renamed, continue to the next file
if ($file.Name -notmatch $pattern) {
continue
}
# Get the work item number from the regular expression, create the
# padded string from it, and define the new filename by replacing
# the original number string with the padded number string.
$workItemNumber = $Matches.WorkItemNumber
$paddedNumber = "{0:d$longestNumeralCount}" -f $workItemNumber
$paddedName = $file.Name -replace $workItemNumber, $paddedNumber
# Rename the file with the padded work item number.
$file | Rename-Item -NewName $paddedName
}
Теперь, когда файлы переименованы, вы можете получить список файлов снова и отсортировать старые и новые файлы по имени. Следующий фрагмент кода снова извлекает файлы для сохранения в новом массиве и сравнения с исходным набором объектов. Затем он сортирует оба массива файлов, сохраняя отсортированные массивы в новые переменные $sortedOriginal
и $sortedPadded
. Наконец, он использует for
цикл для итерации по массивам и вывода объекта со следующими свойствами:
- Индекс представляет текущий индекс в отсортированных массивах.
- Исходный — это элемент в отсортированного массива исходных имен файлов по текущему индексу.
- Padded — это элемент в отсортированном массиве отсортированных имен файлов по текущему индексу.
$paddedList = Get-ChildItem -path ./work_items
# Sort both file lists by name.
$sortedOriginal = $fileList | Sort-Object -Property Name
$sortedPadded = $renamedList | Sort-Object -Property Name
# Iterate over the arrays and output an object to simplify comparing how
# the arrays were sorted before and after padding the work item numbers.
for (
$i = 0
$i -lt $fileList.Count
$i++
) {
[pscustomobject] @{
Index = $i
Original = $sortedOriginal[$i].Name
Padded = $sortedPadded[$i].Name
}
}
Index Original Padded
----- -------- ------
0 bug-219.json bug-00041.json
1 bug-41.json bug-00219.json
2 bug-500.json bug-00500.json
3 bug-697.json bug-00697.json
4 bug-819.json bug-00819.json
5 bug-840.json bug-00840.json
6 feat-176.json feat-00176.json
7 feat-367.json feat-00367.json
8 feat-373.json feat-00373.json
9 feat-434.json feat-00434.json
10 feat-676.json feat-00676.json
11 feat-690.json feat-00690.json
12 feat-880.json feat-00880.json
13 feat-944.json feat-00944.json
14 maint-103.json maint-00049.json
15 maint-367.json maint-00103.json
16 maint-454.json maint-00367.json
17 maint-49.json maint-00454.json
18 maint-562.json maint-00562.json
19 maint-579.json maint-00579.json
В выходных данных отсортированные рабочие элементы после заполнения находятся в ожидаемом порядке.
См. также
PowerShell