Udostępnij za pośrednictwem


about_For

Krótki opis

Opisuje polecenie języka, którego można użyć do uruchamiania instrukcji na podstawie testu warunkowego.

Długi opis

Instrukcja For (znana również jako For pętla) to konstrukcja języka, której można użyć do utworzenia pętli, która uruchamia polecenia w bloku poleceń, podczas gdy określony warunek daje wartość $true.

Typowym zastosowaniem For pętli jest iterowanie tablicy wartości i działanie na podzestawie tych wartości. W większości przypadków, jeśli chcesz iterować wszystkie wartości w tablicy, rozważ użycie Foreach instrukcji .

Składnia

Poniżej przedstawiono składnię instrukcji For .

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

Symbol zastępczy Init reprezentuje co najmniej jedno polecenie, które są uruchamiane przed rozpoczęciem pętli. Zazwyczaj używasz części init instrukcji do utworzenia i zainicjowania zmiennej z wartością początkową.

Ta zmienna będzie następnie podstawą do przetestowania warunku w następnej części instrukcji For .

Symbol zastępczy Warunek reprezentuje część instrukcji For rozpoznawanej $true jako wartość logiczna lub $false . Program PowerShell ocenia warunek za każdym razem, gdy pętla jest uruchamiana For . Jeśli instrukcja to $true, polecenia w bloku poleceń są uruchamiane, a instrukcja zostanie ponownie obliczona. Jeśli warunek jest nadal $true, polecenia na liście Instrukcje są uruchamiane ponownie. Pętla jest powtarzana do momentu, aż warunek stanie się $false.

Symbol zastępczy Powtórz reprezentuje co najmniej jedno polecenie rozdzielone przecinkami, które są wykonywane za każdym razem, gdy pętla powtarza się. Zazwyczaj jest to używane do modyfikowania zmiennej, która jest testowana wewnątrz części Warunek instrukcji .

Symbol zastępczy listy Instrukcje reprezentuje zestaw co najmniej jednego polecenia, które są uruchamiane za każdym razem, gdy pętla zostanie wprowadzona lub powtórzona. Zawartość listy instrukcji jest otoczona nawiasami klamrowymi.

Obsługa wielu operacji

Następujące składnie są obsługiwane w przypadku wielu operacji przypisania w instrukcji 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"
}

Następujące składnie są obsługiwane w przypadku wielu operacji przypisania w instrukcji 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"
}

Uwaga

Operacje inne niż przyrost wstępny lub post mogą nie działać ze wszystkimi składniami.

W przypadku wielu warunków użyj operatorów logicznych, jak pokazano w poniższym przykładzie.

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

Aby uzyskać więcej informacji, zobacz about_Logical_Operators.

Przykłady składni

Co najmniej For instrukcja wymaga nawiasu otaczającego element Init, Condition i Repeat części instrukcji oraz polecenia otoczonego nawiasami klamrowymi w części instrukcji.

Należy pamiętać, że nadchodzące przykłady celowo pokazują kod poza instrukcją For . W kolejnych przykładach kod jest zintegrowany z instrukcją For .

Na przykład poniższa For instrukcja stale wyświetla wartość $i zmiennej do momentu ręcznego przerwania polecenia przez naciśnięcie CTRL+C.

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

Do listy instrukcji można dodać dodatkowe polecenia, aby wartość parametru $i została zwiększana o 1 za każdym razem, gdy pętla jest uruchamiana, jak pokazano w poniższym przykładzie.

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

Dopóki nie zostanie przerwane polecenie, naciskając CTRL+C, ta instrukcja będzie stale wyświetlać wartość $i zmiennej, ponieważ jest zwiększana o 1 przy każdym uruchomieniu pętli.

Zamiast zmieniać wartość zmiennej na liście instrukcji w For części instrukcji, możesz zamiast tego użyć części For Repeat instrukcji w następujący sposób.

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

Ta instrukcja będzie nadal powtarzać się w nieskończoność, dopóki nie zostanie przerwane polecenie, naciskając CTRL+C.

Pętlę For można zakończyć przy użyciu warunku. Warunek można umieścić przy użyciu części Warunek instrukcji For . Pętla For kończy się, gdy warunek zwróci wartość $false.

W poniższym przykładzie pętla For jest uruchamiana, gdy wartość $i jest mniejsza lub równa 10.

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

Zamiast tworzyć i inicjować zmienną poza For instrukcją, można wykonać to zadanie wewnątrz For pętli przy użyciu części Init instrukcji For .

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

Można użyć zwracania karetki zamiast średników, aby rozdzielić części instrukcji Init, Condition i Repeat.For W poniższym przykładzie pokazano, że używa tej alternatywnej For składni.

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

Ta alternatywna forma instrukcji działa w plikach skryptów For programu PowerShell i w wierszu polecenia programu PowerShell. Jednak łatwiej jest użyć For składni instrukcji z średnikami podczas wprowadzania interaktywnych poleceń w wierszu polecenia.

Pętla jest bardziej elastyczna niż Foreach pętlaFor, ponieważ pozwala zwiększać wartości w tablicy lub kolekcji przy użyciu wzorców. W poniższym przykładzie zmienna $i jest zwiększana o 2 w części Repeat instrukcji For .

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

Pętlę For można również napisać w jednym wierszu, jak w poniższym przykładzie.

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

Przykład funkcjonalny

W poniższym przykładzie pokazano, jak można użyć For pętli do iterowania tablicy plików i zmieniania ich nazw. Pliki w folderze work_items mają identyfikator elementu roboczego jako nazwę pliku. Pętla wykonuje iterację po plikach, aby upewnić się, że numer identyfikatora jest zero-padded do pięciu cyfr.

Najpierw kod pobiera listę plików danych elementu roboczego. Są to wszystkie pliki JSON, które używają formatu <work-item-type>-<work-item-number> dla ich nazwy. Dzięki obiektom informacji o pliku zapisanym w zmiennej $fileList można je sortować według nazwy i zobaczyć, że gdy elementy są pogrupowane według typu, kolejność elementów według identyfikatora jest nieoczekiwana.

$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

Aby upewnić się, że można sortować elementy robocze alfanumerycznie, numery elementów roboczych muszą być wyściełane bezobsługowo.

Kod robi to, wyszukując najpierw element roboczy z najdłuższym sufiksem liczbowym. Wykonuje pętlę na plikach przy użyciu for pętli, używając indeksu w celu uzyskania dostępu do każdego pliku w tablicy. Porównuje każdą nazwę pliku ze wzorcem wyrażenia regularnego, aby wyodrębnić numer elementu roboczego jako ciąg zamiast liczby całkowitej. Następnie porównuje długości numerów elementów roboczych, aby znaleźć najdłuższą liczbę.

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

Teraz, gdy znasz maksymalną liczbę liczb dla elementów roboczych, możesz przejąć pliki w pętli, aby zmienić ich nazwy zgodnie z potrzebami. Następny fragment kodu iteruje ponownie listę plików, dopełniając je zgodnie z potrzebami. Używa innego wzorca wyrażenia regularnego, aby przetwarzać tylko pliki z liczbą liczb mniejszą niż maksymalna.

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

Teraz, po zmianie nazwy plików, możesz ponownie pobrać listę plików i posortować zarówno stare, jak i nowe pliki według nazwy. Poniższy fragment kodu pobiera pliki ponownie, aby zapisać je w nowej tablicy i porównać z początkowym zestawem obiektów. Następnie sortuje obie tablice plików, zapisując posortowane tablice do nowych zmiennych $sortedOriginal i $sortedPadded. Na koniec używa for pętli do iterowania tablic i wyprowadzania obiektu o następujących właściwościach:

  • Indeks reprezentuje bieżący indeks w posortowanych tablicach.
  • Oryginalny jest elementem w posortowanej tablicy oryginalnych nazw plików w bieżącym indeksie.
  • Padded to element w posortowanej tablicy wyściełanych nazw plików w bieżącym indeksie.
$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

W danych wyjściowych posortowane elementy robocze po dopełnieniu są w oczekiwanej kolejności.

Zobacz też