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 $false
booleskt $true
värde. PowerShell utvärderar villkoret varje gång loopen For
körs. Om -instruktionen är $true
kö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.