Compartilhar via


about_For

Descrição curta

Descreve um comando de idioma que você pode usar para executar instruções com base em um teste condicional.

Descrição longa

A instrução for (também conhecida como um loop for) é um constructo de linguagem que você pode usar para criar um loop que executa comandos em um bloco de comandos enquanto uma condição especificada é avaliada como $true.

Um uso típico do loop for é 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 instrução foreach.

Sintaxe

O seguinte mostra a sintaxe da instrução for.

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 que a condição seja testada na próxima parte da instrução for.

O espaço reservado Condição representa a parte da instrução for que é resolvida para um valor $true ou $false booliano. O PowerShell avalia a condição sempre que o loop for é executado. Se a instrução for $true, os comandos no bloco de comandos serão executados e a instrução será avaliada novamente. Se a condição ainda estiver $true, os comandos na lista de instruções 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 Condição parte da instrução.

A lista de instruções espaço reservado 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 estão cercados 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 do:

# 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"
}

Nota

Operações diferentes de pré ou pós-incremento podem não funcionar com todas as sintaxes.

Para várias condições de , 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 instrução for requer os parênteses em torno do init, Conditione Repeat parte da instrução e um comando cercado por chaves na lista de Instruções parte da instrução.

Observe que os próximos exemplos mostram intencionalmente o código fora da instrução for. Em exemplos posteriores, o código é integrado à instrução for.

Por exemplo, a instrução for a seguir exibe continuamente o valor da variável $i 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 $i seja incrementado por 1 sempre que o loop for executado, como mostra o exemplo a seguir.

for (;;)
{
    $i++; Write-Host $i
}

Até você sair do comando pressionando CTRL+C, essa instrução exibirá continuamente o valor da variável $i, pois ela é incrementada em 1 sempre que o loop for executado.

Em vez de alterar o valor da variável na parte da lista de instruções da instrução for, você pode usar a parte Repetir da instrução for, 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 loop de for usando uma condição de . Você pode colocar uma condição usando a parte condição da instrução for. O loop for termina quando a condição é avaliada como $false.

No exemplo a seguir, o loop for é 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 instrução for, você pode executar essa tarefa dentro do loop for usando a parte Init da instrução for.

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, Conditione Repeat da instrução for. 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 for funciona em arquivos de script do PowerShell e no prompt de comando do PowerShell. No entanto, é mais fácil usar a sintaxe da instrução for com ponto-e-vírgula quando você insere comandos interativos no prompt de comando.

O loop for é mais flexível do que o loop de foreach porque permite incrementar valores em uma matriz ou coleção usando padrões. No exemplo a seguir, a variável $i é incrementada em 2 na parte Repetir da instrução for.

for ($i = 0; $i -le 20; $i += 2)
{
    Write-Host $i
}

O loop for 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 loop for para iterar em uma matriz de arquivos e renomeá-los. Os arquivos na pasta work_items têm a ID do item de trabalho como nome de arquivo. O loop itera pelos arquivos para garantir que o número da ID seja adicionado a zero a cinco dígitos.

Primeiro, o código recupera a lista de arquivos de dados do item de trabalho. São todos arquivos JSON que usam o formato <work-item-type>-<work-item-number> para seu nome. Com os objetos de informações de arquivo salvos na variável $fileList, você pode classificá-los por nome e ver que, enquanto os itens são 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 do item de trabalho precisam ser adicionados a zero.

O código faz isso primeiro pesquisando o item de trabalho com o sufixo numérico mais longo. Ele faz loops sobre os arquivos usando um loop for, 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 do item de trabalho para localizar 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, você pode fazer loop sobre os arquivos para renomeá-los conforme necessário. O próximo snippet de código itera na 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 são renomeados, você pode recuperar a lista de arquivos novamente e classificar os arquivos antigos e novos pelo 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 ambas as matrizes de arquivos, salvando as matrizes classificadas nas novas variáveis $sortedOriginal e $sortedPadded. Por fim, ele usa um loop for 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 classificada de nomes de arquivo originais no índice atual.
  • adicionado é o item na matriz classificada de nomes de arquivo acolchoados 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.

Consulte também