about_For
Descripción breve
Describe un comando de lenguaje que puede usar para ejecutar instrucciones basadas en una prueba condicional.
Descripción larga
La For
instrucción (también conocida como For
bucle) es una construcción de lenguaje que puede usar para crear un bucle que ejecute comandos en un bloque de comandos mientras una condición especificada se evalúa como $true
.
Un uso típico del For
bucle es iterar una matriz de valores y operar en un subconjunto de estos valores. En la mayoría de los casos, si desea iterar todos los valores de una matriz, considere la posibilidad de usar una Foreach
instrucción .
Sintaxis
A continuación se muestra la sintaxis de la For
instrucción .
for (<Init>; <Condition>; <Repeat>)
{
<Statement list>
}
El marcador de posición Init representa uno o varios comandos que se ejecutan antes de que comience el bucle. Normalmente, se usa la parte Init de la instrucción para crear e inicializar una variable con un valor inicial.
Esta variable será la base de la condición que se va a probar en la siguiente parte de la For
instrucción .
El marcador de posición Condición representa la parte de la For
instrucción que se resuelve en un $true
valor booleano o .$false
PowerShell evalúa la condición cada vez que se ejecuta el For
bucle. Si la instrucción es $true
, los comandos del bloque de comandos se ejecutan y la instrucción se vuelve a evaluar. Si la condición sigue siendo $true
, los comandos de la lista Instrucción se ejecutan de nuevo.
El bucle se repite hasta que la condición se convierte en $false
.
El marcador de posición Repeat representa uno o varios comandos, separados por comas, que se ejecutan cada vez que se repite el bucle. Normalmente, se usa para modificar una variable que se prueba dentro de la parte Condición de la instrucción .
El marcador de posición de lista Instrucción representa un conjunto de uno o varios comandos que se ejecutan cada vez que se escribe o repite el bucle. El contenido de la lista Instrucción está rodeado de llaves.
Compatibilidad con varias operaciones
Se admiten las siguientes sintaxis para varias operaciones de asignación en la instrucción 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"
}
Se admiten las siguientes sintaxis para varias operaciones de asignación en la instrucción 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"
}
Nota:
Es posible que las operaciones que no sean el incremento previo o posterior no funcionen con todas las sintaxis.
En el caso de varias condiciones , use operadores lógicos como se muestra en el ejemplo siguiente.
for (($i = 0), ($j = 0); $i -lt 10 -and $j -lt 10; $i++,$j++)
{
"`$i:$i"
"`$j:$j"
}
Para obtener más información, consulte about_Logical_Operators.
Ejemplos de sintaxis
Como mínimo, una For
instrucción requiere el paréntesis que rodea a la parte Init, Condition y Repeat de la instrucción y un comando rodeado de llaves en la parte de lista Instrucción de la instrucción.
Tenga en cuenta que los próximos ejemplos muestran intencionadamente código fuera de la For
instrucción . En ejemplos posteriores, el código se integra en la For
instrucción .
Por ejemplo, la siguiente For
instrucción muestra continuamente el valor de la $i
variable hasta que se interrumpe manualmente el comando presionando CTRL+C.
$i = 1
for (;;)
{
Write-Host $i
}
Puede agregar comandos adicionales a la lista de instrucciones para que el valor de $i
se incremente en 1 cada vez que se ejecute el bucle, como se muestra en el ejemplo siguiente.
for (;;)
{
$i++; Write-Host $i
}
Hasta que salga del comando presionando CTRL+C, esta instrucción mostrará continuamente el valor de la $i
variable, ya que se incrementa en 1 cada vez que se ejecuta el bucle.
En lugar de cambiar el valor de la variable en la parte de lista de instrucciones de la For
instrucción, puede usar la parte Repeat de la For
instrucción en su lugar, como se indica a continuación.
$i=1
for (;;$i++)
{
Write-Host $i
}
Esta instrucción se repetirá indefinidamente hasta que salga del comando presionando CTRL+C.
Puede finalizar el For
bucle mediante una condición. Puede colocar una condición mediante la parte Condición de la For
instrucción . El For
bucle finaliza cuando la condición se evalúa como $false
.
En el ejemplo siguiente, el For
bucle se ejecuta mientras el valor de $i
es menor o igual que 10.
$i=1
for(;$i -le 10;$i++)
{
Write-Host $i
}
En lugar de crear e inicializar la variable fuera de la For
instrucción , puede realizar esta tarea dentro del For
bucle mediante la parte Init de la For
instrucción .
for($i=1; $i -le 10; $i++){Write-Host $i}
Puede usar retornos de carro en lugar de punto y coma para delimitar las partes Init, Condition y Repeat de la For
instrucción. En el ejemplo siguiente se muestra un For
que usa esta sintaxis alternativa.
for ($i = 0
$i -lt 10
$i++){
$i
}
Esta forma alternativa de la For
instrucción funciona en archivos de script de PowerShell y en el símbolo del sistema de PowerShell. Sin embargo, es más fácil usar la sintaxis de instrucción For
con punto y coma al escribir comandos interactivos en el símbolo del sistema.
El For
bucle es más flexible que el Foreach
bucle porque permite incrementar los valores de una matriz o colección mediante patrones. En el ejemplo siguiente, la $i
variable se incrementa en 2 en la parte Repeat de la For
instrucción .
for ($i = 0; $i -le 20; $i += 2)
{
Write-Host $i
}
El For
bucle también se puede escribir en una línea como en el ejemplo siguiente.
for ($i = 0; $i -lt 10; $i++) { Write-Host $i }
Ejemplo funcional
En el ejemplo siguiente se muestra cómo puede usar un For
bucle para recorrer en iteración una matriz de archivos y cambiarles el nombre. Los archivos de la work_items
carpeta tienen su identificador de elemento de trabajo como nombre de archivo. El bucle recorre en iteración los archivos para asegurarse de que el número de identificador se rellena a cero en cinco dígitos.
En primer lugar, el código recupera la lista de archivos de datos del elemento de trabajo. Son todos los archivos JSON que usan el formato <work-item-type>-<work-item-number>
para su nombre.
Con los objetos de información de archivo guardados en la $fileList
variable, puede ordenarlos por nombre y ver que mientras los elementos se agrupan por tipo, el orden de los elementos por identificador es inesperado.
$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
Para asegurarse de que puede ordenar los elementos de trabajo de forma alfanumérica, los números del elemento de trabajo deben rellenarse en cero.
El código lo hace buscando primero el elemento de trabajo con el sufijo numérico más largo. Recorre en bucle los archivos mediante un for
bucle , utilizando el índice para acceder a cada archivo de la matriz. Compara cada nombre de archivo con un patrón de expresión regular para extraer el número del elemento de trabajo como una cadena en lugar de un entero. A continuación, compara las longitudes de los números del elemento de trabajo para encontrar el número más largo.
# 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
}
}
}
Ahora que conoce el número máximo de números de los elementos de trabajo, puede recorrer en bucle los archivos para cambiarles el nombre según sea necesario. El siguiente fragmento de código recorre en iteración la lista de archivos de nuevo y los rellena según sea necesario. Usa otro patrón de expresión regular para procesar solo los archivos con un recuento numérico menor que el máximo.
# 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
}
Ahora que se cambia el nombre de los archivos, puede recuperar la lista de archivos de nuevo y ordenar los archivos antiguos y nuevos por nombre. El fragmento de código siguiente recupera de nuevo los archivos para guardarlos en una nueva matriz y compararlo con el conjunto inicial de objetos. A continuación, ordena ambas matrices de archivos, guardando las matrices ordenadas en las nuevas variables $sortedOriginal
y $sortedPadded
. Por último, usa un for
bucle para recorrer en iteración las matrices y generar un objeto con las siguientes propiedades:
- Índice representa el índice actual en las matrices ordenadas.
- Original es el elemento de la matriz ordenada de nombres de archivo originales en el índice actual.
- El elemento rellenado es el elemento de la matriz ordenada de nombres de archivo rellenados en el índice actual.
$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
En la salida, los elementos de trabajo ordenados después del relleno están en el orden esperado.