about_For
Descrição breve
Descreve um comando de linguagem que você pode usar para executar instruções com base em um teste condicional.
Descrição longa
A For
instrução (também conhecida como For
loop) é uma construção de linguagem que você pode usar para criar um loop que executa comandos em um bloco de comando enquanto uma condição especificada é avaliada como $true
.
Um uso típico do For
loop é iterar uma matriz de valores e operar em um subconjunto desses valores. Na maioria dos casos, se você quiser iterar todos os valores em uma matriz, considere usar uma Foreach
instrução.
Sintaxe
Veja a seguir a sintaxe da For
instrução.
for (<Init>; <Condition>; <Repeat>)
{
<Statement list>
}
O espaço reservado Init representa um ou mais comandos que são executados antes do início do loop. Normalmente, você usa a parte Init da instrução para criar e inicializar uma variável com um valor inicial.
Essa variável será então a base para a condição a ser testada na próxima parte da For
instrução.
O espaço reservado Condition representa a For
parte da instrução que é resolvida para um $true
valor booliano ou $false
. O PowerShell avalia a condição sempre que o For
loop é executado. Se a instrução for $true
, os comandos no bloco de comando serão executados e a instrução será avaliada novamente. Se a condição ainda $true
for , os comandos na lista Instrução serão executados novamente.
O loop é repetido até que a condição se torne $false
.
O espaço reservado Repetir representa um ou mais comandos, separados por vírgulas, que são executados sempre que o loop se repete. Normalmente, isso é usado para modificar uma variável que é testada dentro da parte Condition da instrução.
O espaço reservado da lista de instruções representa um conjunto de um ou mais comandos que são executados sempre que o loop é inserido ou repetido. O conteúdo da lista de instruções é cercado por chaves.
Suporte para várias operações
As seguintes sintaxes têm suporte para várias operações de atribuição na instrução 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"
}
As seguintes sintaxes têm suporte para várias operações de atribuição na instrução 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"
}
Observação
Operações diferentes de pré ou pós-incremento podem não funcionar com todas as sintaxes.
Para várias condições, use operadores lógicos, conforme demonstrado pelo exemplo a seguir.
for (($i = 0), ($j = 0); $i -lt 10 -and $j -lt 10; $i++,$j++)
{
"`$i:$i"
"`$j:$j"
}
Para obter mais informações, consulte about_Logical_Operators.
Exemplos de sintaxe
No mínimo, uma For
instrução requer o parêntese em torno da parte Init, Condition e Repeat da instrução e um comando entre chaves na parte da lista Statement da instrução.
Observe que os próximos exemplos mostram intencionalmente o código fora da For
instrução. Em exemplos posteriores, o código é integrado à For
instrução.
Por exemplo, a instrução a seguir For
exibe continuamente o $i
valor da variável até que você saia manualmente do comando pressionando CTRL+C.
$i = 1
for (;;)
{
Write-Host $i
}
Você pode adicionar comandos adicionais à lista de instruções para que o valor de seja incrementado em 1 cada vez que o loop for executado, como mostra o exemplo a $i
seguir.
for (;;)
{
$i++; Write-Host $i
}
Até que você saia do comando pressionando CTRL+C, essa instrução exibirá continuamente o valor da variável à medida que ela é incrementada $i
em 1 cada vez que o loop é executado.
Em vez de alterar o valor da variável na parte da lista de instruções da For
instrução, você pode usar a parte Repeat da For
instrução, da seguinte maneira.
$i=1
for (;;$i++)
{
Write-Host $i
}
Essa instrução ainda será repetida indefinidamente até que você saia do comando pressionando CTRL+C.
Você pode encerrar o For
loop usando uma condição. Você pode colocar uma condição usando a parte Condition da For
instrução. O For
loop termina quando a condição é avaliada como $false
.
No exemplo a seguir, o For
loop é executado enquanto o valor de $i
é menor ou igual a 10.
$i=1
for(;$i -le 10;$i++)
{
Write-Host $i
}
Em vez de criar e inicializar a variável fora da For
instrução, você pode executar essa tarefa dentro do For
loop usando a parte Init da For
instrução.
for($i=1; $i -le 10; $i++){Write-Host $i}
Você pode usar retornos de carro em vez de ponto-e-vírgula para delimitar as partes Init, Condition e Repeat da For
instrução. O exemplo a seguir mostra um For
que usa essa sintaxe alternativa.
for ($i = 0
$i -lt 10
$i++){
$i
}
Essa forma alternativa da instrução funciona em arquivos de script do PowerShell e no prompt de For
comando do PowerShell. No entanto, é mais fácil usar a sintaxe da For
instrução com ponto-e-vírgula quando você insere comandos interativos no prompt de comando.
O For
loop é mais flexível do que o Foreach
loop porque permite incrementar valores em uma matriz ou coleção usando padrões. No exemplo a seguir, a variável é incrementada $i
em 2 na parte Repeat da For
instrução.
for ($i = 0; $i -le 20; $i += 2)
{
Write-Host $i
}
O For
loop também pode ser escrito em uma linha, como no exemplo a seguir.
for ($i = 0; $i -lt 10; $i++) { Write-Host $i }
Exemplo funcional
O exemplo a seguir demonstra como você pode usar um For
loop para iterar em uma matriz de arquivos e renomeá-los. Os arquivos na work_items
pasta têm sua ID de item de trabalho como o nome do arquivo. O loop itera pelos arquivos para garantir que o número de ID seja preenchido com zero para cinco dígitos.
Primeiro, o código recupera a lista de arquivos de dados do item de trabalho. Eles são todos arquivos JSON que usam o formato <work-item-type>-<work-item-number>
para seu nome.
Com os objetos de informações do arquivo salvos na $fileList
variável, você pode classificá-los por nome e ver que, embora os itens sejam agrupados por tipo, a ordenação dos itens por ID é inesperada.
$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 garantir que você possa classificar os itens de trabalho alfanumericamente, os números de item de trabalho precisam ser preenchidos com zero.
O código faz isso pesquisando primeiro o item de trabalho com o sufixo numérico mais longo. Ele faz um loop sobre os arquivos usando um for
loop, usando o índice para acessar cada arquivo na matriz. Ele compara cada nome de arquivo a um padrão de expressão regular para extrair o número do item de trabalho como uma cadeia de caracteres em vez de um inteiro. Em seguida, ele compara os comprimentos dos números de item de trabalho para encontrar o número mais longo.
# 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
}
}
}
Agora que você sabe a contagem máxima de numerais para os itens de trabalho, pode fazer um loop sobre os arquivos para renomeá-los conforme necessário. O próximo trecho de código itera sobre a lista de arquivos novamente, preenchendo-os conforme necessário. Ele usa outro padrão de expressão regular para processar apenas arquivos com uma contagem de numerais menor que o 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
}
Agora que os arquivos foram renomeados, você pode recuperar a lista de arquivos novamente e classificar os arquivos antigos e novos por nome. O snippet a seguir recupera os arquivos novamente para salvar em uma nova matriz e comparar com o conjunto inicial de objetos. Em seguida, ele classifica as duas matrizes de arquivos, salvando as matrizes classificadas nas novas variáveis $sortedOriginal
e $sortedPadded
. Por fim, ele usa um for
loop para iterar sobre as matrizes e gerar um objeto com as seguintes propriedades:
- Index representa o índice atual nas matrizes classificadas.
- Original é o item na matriz ordenada de nomes de arquivos originais no índice atual.
- Padded é o item na matriz classificada de nomes de arquivos preenchidos no índice atual.
$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
Na saída, os itens de trabalho classificados após o preenchimento estão na ordem esperada.