about_For

Descrizione breve

Descrive un comando di linguaggio che è possibile usare per eseguire istruzioni basate su un test condizionale.

Descrizione lunga

L'istruzione For (nota anche come For ciclo) è un costrutto di linguaggio che è possibile usare per creare un ciclo che esegue comandi in un blocco di comandi mentre una condizione specificata restituisce $true.

Un uso tipico del ciclo consiste nell'iterazione For di una matrice di valori e nell'operare su un subset di questi valori. Nella maggior parte dei casi, se si desidera eseguire l'iterazione di tutti i valori in una matrice, è consigliabile usare un'istruzione Foreach .

Sintassi

Di seguito viene illustrata la sintassi dell'istruzione For .

for (<Init>; <Condition>; <Repeat>)
{
    <Statement list>
}

Il segnaposto Init rappresenta uno o più comandi eseguiti prima dell'inizio del ciclo. In genere si usa la parte Init dell'istruzione per creare e inizializzare una variabile con un valore iniziale.

Questa variabile sarà quindi la base per la condizione da testare nella parte successiva dell'istruzione For .

Il segnaposto Condition rappresenta la parte dell'istruzione For che viene risolta in un $true valore booleano o $false . PowerShell valuta la condizione ogni volta che viene eseguito il For ciclo. Se l'istruzione è $true, i comandi nel blocco di comandi vengono eseguiti e l'istruzione viene valutata di nuovo. Se la condizione è ancora $true, i comandi nell'elenco Istruzioni vengono eseguiti di nuovo. Il ciclo viene ripetuto fino a quando la condizione non diventa $false.

Il segnaposto Repeat rappresenta uno o più comandi, separati da virgole, che vengono eseguiti ogni volta che il ciclo viene ripetuto. In genere, viene usato per modificare una variabile testata all'interno della parte Condition dell'istruzione .

Il segnaposto elenco istruzioni rappresenta un set di uno o più comandi eseguiti ogni volta che il ciclo viene immesso o ripetuto. Il contenuto dell'elenco Istruzioni è racchiuso tra parentesi graffe.

Supporto per più operazioni

Le sintassi seguenti sono supportate per più operazioni di assegnazione nell'istruzione 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"
}

Le sintassi seguenti sono supportate per più operazioni di assegnazione nell'istruzione 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

Le operazioni diverse da pre o post increment possono non funzionare con tutte le sintassi.

Per più condizioni usare operatori logici, come illustrato nell'esempio seguente.

for (($i = 0), ($j = 0); $i -lt 10 -and $j -lt 10; $i++,$j++)
{
    "`$i:$i"
    "`$j:$j"
}

Per altre informazioni, vedere about_Logical_Operators.

Esempi di sintassi

Come minimo, un'istruzione For richiede la parentesi che circonda la parte Init, Condition e Repeat dell'istruzione e un comando racchiuso tra parentesi graffe nella parte dell'elenco Istruzioni dell'istruzione.

Si noti che gli esempi futuri mostrano intenzionalmente il codice all'esterno dell'istruzione For . Negli esempi successivi il codice è integrato nell'istruzione For .

Ad esempio, l'istruzione seguente For visualizza continuamente il valore della $i variabile fino a quando non si interrompe manualmente il comando premendo CTRL+C.

$i = 1
for (;;)
{
    Write-Host $i
}

È possibile aggiungere altri comandi all'elenco di istruzioni in modo che il valore di $i venga incrementato di 1 ogni volta che viene eseguito il ciclo, come illustrato nell'esempio seguente.

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

Finché non si interrompe il comando premendo CTRL+C, questa istruzione visualizzerà continuamente il valore della $i variabile man mano che viene incrementato di 1 ogni volta che viene eseguito il ciclo.

Anziché modificare il valore della variabile nella parte dell'elenco di istruzioni dell'istruzione For , è possibile usare invece la parte Repeat dell'istruzione For , come indicato di seguito.

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

Questa istruzione verrà ripetuta a tempo indeterminato fino a quando non si interrompe il comando premendo CTRL+C.

È possibile terminare il For ciclo usando una condizione. È possibile inserire una condizione usando la parte Condizione dell'istruzione For . Il For ciclo termina quando la condizione restituisce $false.

Nell'esempio seguente il For ciclo viene eseguito mentre il valore di $i è minore o uguale a 10.

$i=1
for(;$i -le 10;$i++)
{
    Write-Host $i
}

Anziché creare e inizializzare la variabile all'esterno dell'istruzione For , è possibile eseguire questa attività all'interno del For ciclo usando la parte Init dell'istruzione For .

for($i=1; $i -le 10; $i++){Write-Host $i}

È possibile utilizzare i ritorni a capo anziché i punti e virgola per delimitare le parti Init, Condition e Repeat dell'istruzione For . Nell'esempio seguente viene illustrato un For oggetto che usa questa sintassi alternativa.

for ($i = 0
  $i -lt 10
  $i++){
  $i
}

Questa forma alternativa dell'istruzione For funziona nei file di script di PowerShell e al prompt dei comandi di PowerShell. Tuttavia, è più semplice usare la sintassi dell'istruzione For con punti e virgola quando si immettono comandi interattivi al prompt dei comandi.

Il For ciclo è più flessibile del Foreach ciclo perché consente di incrementare i valori in una matrice o in una raccolta usando i criteri. Nell'esempio seguente la $i variabile viene incrementata di 2 nella parte Repeat dell'istruzione For .

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

Il For ciclo può anche essere scritto su una riga come nell'esempio seguente.

for ($i = 0; $i -lt 10; $i++) { Write-Host $i }

Esempio funzionale

Nell'esempio seguente viene illustrato come usare un For ciclo per scorrere una matrice di file e rinominarli. I file nella work_items cartella hanno il relativo ID elemento di lavoro come nome file. Il ciclo scorre i file per assicurarsi che il numero ID sia riempito da zero a cinque cifre.

Innanzitutto, il codice recupera l'elenco dei file di dati degli elementi di lavoro. Sono tutti file JSON che usano il formato <work-item-type>-<work-item-number> per il nome. Con gli oggetti informazioni file salvati nella $fileList variabile, è possibile ordinarli in base al nome e vedere che mentre gli elementi sono raggruppati per tipo, l'ordinamento degli elementi in base all'ID è imprevisto.

$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

Per garantire che sia possibile ordinare gli elementi di lavoro in modo alfanumerico, i numeri degli elementi di lavoro devono essere riempiti senza riempimento.

Il codice esegue questa operazione cercando prima l'elemento di lavoro con il suffisso numerico più lungo. Esegue un ciclo sui file usando un for ciclo, usando l'indice per accedere a ogni file nella matrice. Confronta ogni nome file con un criterio di espressione regolare per estrarre il numero dell'elemento di lavoro come stringa anziché un numero intero. Confronta quindi le lunghezze dei numeri dell'elemento di lavoro per trovare il numero più lungo.

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

Ora che si conosce il numero massimo di numeri per gli elementi di lavoro, è possibile eseguire il ciclo sui file per rinominarli in base alle esigenze. Il frammento di codice successivo esegue di nuovo l'iterazione dell'elenco di file, spaziandoli in base alle esigenze. Usa un altro modello di espressione regolare per elaborare solo i file con un conteggio numerale inferiore al valore massimo.

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

Ora che i file vengono rinominati, è possibile recuperare di nuovo l'elenco dei file e ordinare i file precedenti e nuovi in base al nome. Il frammento di codice seguente recupera nuovamente un file per salvare in una nuova matrice e confrontarlo con il set iniziale di oggetti. Ordina quindi entrambe le matrici di file, salvando le matrici ordinate nelle nuove variabili $sortedOriginal e $sortedPadded. Infine, usa un for ciclo per scorrere le matrici e restituire un oggetto con le proprietà seguenti:

  • Index rappresenta l'indice corrente nelle matrici ordinate.
  • Original è l'elemento nella matrice ordinata di nomi file originali in corrispondenza dell'indice corrente.
  • Padded è l'elemento nella matrice ordinata di nomi file riempiti in corrispondenza dell'indice corrente.
$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

Nell'output gli elementi di lavoro ordinati dopo la spaziatura interna sono nell'ordine previsto.

Vedi anche