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 för 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 for-loopen ä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 syntaxen för for-instruktionen.

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 del 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 for-instruktionen.

Platshållaren Condition representerar den del av for-instruktionen som matchar ett $true- eller $falsebooleskt värde. PowerShell utvärderar villkoret varje gång for-loopen körs. Om -instruktionen är $truekörs kommandona i kommandoblocket och -instruktionen utvärderas igen. Om villkoret fortfarande är $truekommandona 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. Detta används vanligtvis för att ändra en variabel som testas i Condition del av -instruktionen.

-instruktionslistan platshållare 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 instruktionen 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"
}

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

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

Not

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

För flera villkor använder 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

Minst kräver en for-instruktion parentesen som omger Init, Conditionoch Repeat part of the statement och ett kommando omgivet av klammerparenteser i -instruktionslistan del av -instruktionen.

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

Följande for-instruktion visar till exempel 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 för $i ökas med 1 varje gång loopen körs, vilket visas i följande exempel.

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

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

I stället för att ändra värdet för variabeln i instruktionslistan i for-instruktionen kan du använda Upprepa del av for-instruktionen 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 for-loopen med hjälp av ett villkor. Du kan placera ett villkor med hjälp av Villkor delen av for-instruktionen. for-loopen avslutas när villkoret utvärderas till $false.

I följande exempel körs for-loopen medan värdet för $i ä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 for-instruktionen kan du utföra den här uppgiften i for-loopen med hjälp av Init del av for-instruktionen.

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 Init, Villkoroch Upprepa delar av for-instruktionen. 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 for-instruktionen fungerar i PowerShell-skriptfiler och i PowerShell-kommandotolken. Det är dock enklare att använda for-instruktionssyntaxen med semikolon när du anger interaktiva kommandon i kommandotolken.

for-loopen är mer flexibel än den foreach loopen eftersom du kan öka värden i en matris eller samling med hjälp av mönster. I följande exempel ökas variabeln $i med 2 i Upprepa del av for-instruktionen.

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

Den for-loopen 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 mappen work_items 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 sparas 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.
  • Vadderad ä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