Dela via


about_For

Kort beskrivning

Beskriver ett språkkommando som du kan använda för att köra instruktioner baserat på ett villkorstest.

Lång beskrivning

-instruktionen For (kallas även en For loop) är en språkkonstruktion som du kan använda för att skapa en loop som kör kommandon i ett kommandoblock medan ett angivet villkor utvärderas till $true.

En vanlig användning av loopen For är att iterera en matris med värden och att arbeta på en delmängd av dessa värden. Om du i de flesta fall vill iterera alla värden i en matris bör du överväga att använda en Foreach -instruktion.

Syntax

Följande visar instruktionssyntaxen For .

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

Platshållaren Init representerar ett eller flera kommandon som körs innan loopen börjar. Du använder vanligtvis Init-delen av -instruktionen för att skapa och initiera en variabel med ett startvärde.

Den här variabeln utgör sedan grunden för villkoret som ska testas i nästa del av -instruktionen For .

Platshållaren Villkor representerar den del av -instruktionen For som matchar ett eller $falsebooleskt $true värde. PowerShell utvärderar villkoret varje gång loopen For körs. Om -instruktionen är $truekörs kommandona i kommandoblocket och -instruktionen utvärderas igen. Om villkoret fortfarande $trueär körs kommandona i instruktionslistan igen. Loopen upprepas tills villkoret blir $false.

Platshållaren Upprepa representerar ett eller flera kommandon, avgränsade med kommatecken, som körs varje gång loopen upprepas. Vanligtvis används detta för att ändra en variabel som testas i villkorsdelen av -instruktionen.

Platshållaren för instruktionslistan representerar en uppsättning med ett eller flera kommandon som körs varje gång loopen anges eller upprepas. Innehållet i instruktionslistan omges av klammerparenteser.

Stöd för flera åtgärder

Följande syntaxer stöds för flera tilldelningsåtgärder i Init-instruktionen:

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

Följande syntaxer stöds för flera tilldelningsåtgärder i repeat-instruktionen:

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

Kommentar

Andra åtgärder än inkrement före eller efter kanske inte fungerar med alla syntaxer.

För flera villkor använder du logiska operatorer, vilket visas i följande exempel.

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

Mer information finns i about_Logical_Operators.

Syntaxexempel

Som minst kräver en For -instruktion parentesen som omger init-, villkors- och upprepa-delen av -instruktionen och ett kommando omgivet av klammerparenteser i instruktionslistans del av -instruktionen.

Observera att de kommande exemplen avsiktligt visar kod utanför -instruktionen For . I senare exempel integreras kod i -instruktionen For .

Följande instruktion visar till exempel For kontinuerligt värdet för variabeln $i tills du bryter ut kommandot manuellt genom att trycka på CTRL+C.

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

Du kan lägga till ytterligare kommandon i instruktionslistan så att värdet $i för ökas med 1 varje gång loopen körs, vilket visas i följande exempel.

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

Tills du bryter ut kommandot genom att trycka på CTRL+C, visar den här instruktionen kontinuerligt värdet för variabeln $i eftersom den ökas med 1 varje gång loopen körs.

I stället för att ändra värdet för variabeln i instruktionslistans del av -instruktionen For kan du använda instruktionen For Upprepa i stället, enligt följande.

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

Den här instruktionen upprepas fortfarande på obestämd tid tills du bryter ut kommandot genom att trycka på CTRL+C.

Du kan avsluta loopen For med ett villkor. Du kan placera ett villkor med hjälp av villkorsdelen av -instruktionenFor. Loopen For avslutas när villkoret utvärderas till $false.

I följande exempel körs loopen For medan värdet $i för är mindre än eller lika med 10.

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

I stället för att skapa och initiera variabeln utanför -instruktionen For kan du utföra den här uppgiften i loopen For med hjälp av Init-delen av -instruktionen For .

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

Du kan använda vagnreturer i stället för semikolon för att avgränsa delarna Init, Condition och Repeat i -instruktionen For . I följande exempel visas en For som använder den här alternativa syntaxen.

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

Den här alternativa formen av -instruktionen For fungerar i PowerShell-skriptfiler och i PowerShell-kommandotolken. Det är dock enklare att använda instruktionssyntaxen For med semikolon när du anger interaktiva kommandon i kommandotolken.

Loopen For är mer flexibel än loopen Foreach eftersom du kan öka värdena i en matris eller samling med hjälp av mönster. I följande exempel ökas variabeln $i med 2 i instruktionen For Upprepa.

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

Loopen For kan också skrivas på en rad som i följande exempel.

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

Funktionellt exempel

I följande exempel visas hur du kan använda en For loop för att iterera över en matris med filer och byta namn på dem. Filerna i work_items mappen har arbetsobjektets ID som filnamn. Loopen itererar genom filerna för att säkerställa att ID-numret är noll-vadderat till fem siffror.

Först hämtar koden listan över arbetsobjektsdatafiler. De är alla JSON-filer som använder formatet <work-item-type>-<work-item-number> för sitt namn. När filinformationsobjekten har sparats i variabeln $fileList kan du sortera dem efter namn och se att objekt grupperas efter typ, men att ordningen på objekten efter ID är oväntad.

$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

För att säkerställa att du kan sortera arbetsobjekten alfanumeriskt måste arbetsobjektsnumren vara noll-vadderade.

Koden gör detta genom att först söka efter arbetsobjektet med det längsta numeriska suffixet. Den loopar över filerna med hjälp av en for loop med hjälp av indexet för att komma åt varje fil i matrisen. Den jämför varje filnamn med ett mönster för reguljära uttryck för att extrahera arbetsobjektnumret som en sträng i stället för ett heltal. Sedan jämförs längden på arbetsobjektsnumren för att hitta det längsta talet.

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

Nu när du vet det maximala antalet siffror för arbetsobjekten kan du loopa över filerna för att byta namn på dem efter behov. Nästa kodfragment itererar över fillistan igen och utfyllnad av dem efter behov. Det använder ett annat mönster för reguljära uttryck för att endast bearbeta filer med ett talantal som är mindre än det maximala.

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

Nu när filerna har bytt namn kan du hämta listan över filer igen och sortera både gamla och nya filer efter namn. Följande kodfragment hämtar filerna igen för att spara i en ny matris och jämföras med den första uppsättningen objekt. Sedan sorterar den båda matriserna med filer och sparar de sorterade matriserna i de nya variablerna $sortedOriginal och $sortedPadded. Slutligen använder den en for loop för att iterera över matriserna och mata ut ett objekt med följande egenskaper:

  • Index representerar det aktuella indexet i de sorterade matriserna.
  • Original är objektet i den sorterade matrisen med ursprungliga filnamn i det aktuella indexet.
  • Vadderat är objektet i den sorterade matrisen med vadderade filnamn i det aktuella indexet.
$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

I utdata är de sorterade arbetsobjekten efter utfyllnad i förväntad ordning.

Se även