Megosztás a következőn keresztül:


about_For

Rövid leírás

Egy feltételes teszten alapuló utasítások futtatására használható nyelvi parancsot ismertet.

Hosszú leírás

A for utasítás (más néven for hurok) egy olyan nyelvi szerkezet, amellyel parancsokat futtathat egy parancsblokkban, miközben egy adott feltétel kiértékelése $true.

A for hurok tipikus használata az értékek tömbjének iterálása és ezeknek az értékeknek egy részhalmazán való működés. A legtöbb esetben, ha egy tömb összes értékét meg szeretné iterálni, fontolja meg egy foreach utasítás használatát.

Szintaxis

Az alábbiakban a for utasítás szintaxisa látható.

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

A Init helyőrző egy vagy több parancsot jelöl, amelyek a ciklus megkezdése előtt futnak. Az utasítás Init része általában egy kezdő értékkel rendelkező változó létrehozásához és inicializálásához használható.

Ez a változó lesz a for utasítás következő részében tesztelendő feltétel alapja.

A feltétel helyőrző a for utasítás azon részét jelöli, amely egy $true vagy $falselogikai értékre van feloldva. A PowerShell minden alkalommal kiértékeli a feltételt, amikor a for ciklus fut. Ha az utasítás $true, a parancsblokk parancsai futnak, és a rendszer ismét kiértékeli az utasítást. Ha a feltétel továbbra is $true, a utasításlistában szereplő parancsok újra futni. A ciklus addig ismétlődik, amíg a feltétel $falsenem lesz.

Az Ismétlés helyőrző egy vagy több, vesszővel elválasztott parancsot jelöl, amelyeket a rendszer minden alkalommal végrehajt, amikor a ciklus ismétlődik. Ez általában egy olyan változó módosítására szolgál, amelyet a Feltétel utasításban tesztelnek.

A utasításlista helyőrző egy vagy több parancskészletet jelöl, amelyek minden alkalommal futnak, amikor a ciklus be van írva vagy ismétlődik. A utasításlista tartalmát kapcsos zárójelek veszik körül.

Több művelet támogatása

Az Init utasításban a következő szintaxisok támogatottak:

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

A Repeat utasításban a következő szintaxisok támogatottak:

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

Jegyzet

Az előzetes és a utólagos növekménytől eltérő műveletek nem feltétlenül működnek az összes szintaxissal.

Több feltétel esetén használjon logikai operátorokat az alábbi példában bemutatott módon.

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

További információ: about_Logical_Operators.

Szintaxisbeli példák

Egy for utasításhoz legalább a Init, Feltételés Az utasítás ismétlése része, valamint a Utasításlistában kapcsos zárójelekkel körülvett parancs utasítás része.

Vegye figyelembe, hogy a közelgő példák szándékosan a for utasításon kívüli kódot mutatnak. A későbbi példákban a kód integrálva lesz a for utasításba.

Az alábbi for utasítás például folyamatosan megjeleníti a $i változó értékét, amíg manuálisan nem lép ki a parancsból a CTRL+C billentyűkombináció lenyomásával.

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

További parancsokat is hozzáadhat az utasításlistához, hogy a ciklus futtatásakor a $i értéke 1-zel nőjön, ahogy az alábbi példa is mutatja.

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

Amíg a CTRL+C billentyűkombinációval nem lép ki a parancsból, ez az utasítás folyamatosan megjeleníti a $i változó értékét, mivel a ciklus minden futtatásakor 1-zel növekszik.

A for utasítás utasításlista részén lévő változó értékének módosítása helyett a utasítás for részét használhatja az alábbiak szerint.

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

Ez az utasítás továbbra is határozatlan ideig ismétlődik, amíg ki nem lép a parancsból a CTRL+C billentyűkombináció lenyomásával.

A for hurok egy feltétellel. A feltételt a utasítás for részének használatával helyezheti el. A for ciklus akkor fejeződik be, amikor a feltétel kiértékelése $false.

Az alábbi példában a for ciklus fut, míg a $i értéke kisebb vagy egyenlő 10-nél.

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

A for utasításon kívüli változó létrehozása és inicializálása helyett ezt a feladatot a for cikluson belül hajthatja végre a Initfor utasítás részével.

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

Pontosvesszők helyett kocsivisszajelekkel elválaszthatja a Init, Feltétel, és részeinek ismétlését. Az alábbi példa egy olyan for mutat be, amely ezt az alternatív szintaxist használja.

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

A for utasítás ezen alternatív formája PowerShell-szkriptfájlokban és a PowerShell parancssorában működik. A for utasítás szintaxisa azonban könnyebben használható pontosvesszővel, amikor interaktív parancsokat ad meg a parancssorban.

A for hurok rugalmasabb, mint a foreach hurok, mivel lehetővé teszi a tömbök vagy gyűjtemények értékeinek mintákkal történő növelését. Az alábbi példában a $i változó 2-zel növekszik a utasítás for részében.

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

A for hurok is megírható egy sorban, mint az alábbi példában.

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

Funkcionális példa

Az alábbi példa bemutatja, hogyan használhat egy for hurkot a fájlok tömbjének iterálására és átnevezésére. A work_items mappában lévő fájlok fájlneve a munkaelem-azonosítójuk. A hurok végighalad a fájlokon, hogy az azonosítószám nulla legyen öt számjegyre állítva.

Először a kód lekéri a munkaelem-adatfájlok listáját. Ezek mind olyan JSON-fájlok, amelyek a nevükhöz <work-item-type>-<work-item-number> formátumot használják. Ha a fájlinformációs objektumokat a $fileList változóba menti, név szerint rendezheti őket, és láthatja, hogy míg az elemek típus szerint vannak csoportosítva, az elemek azonosító szerinti sorrendje váratlan.

$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

Annak érdekében, hogy a munkaelemeket alfanumerikusan rendezhesse, a munkaelemszámokat nullával kell elválasztani.

A kód ezt úgy teszi meg, hogy először megkeresi a leghosszabb numerikus utótaggal rendelkező munkaelemet. Egy for hurok használatával hurkolja át a fájlokat, és az index használatával éri el a tömb egyes fájljait. Az egyes fájlneveket egy reguláris kifejezésmintával hasonlítja össze, így a munkaelem számát sztringként nyeri ki egész szám helyett. Ezután összehasonlítja a munkaelem-számok hosszát a leghosszabb szám megtalálásához.

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

Most, hogy megismerte a munkaelemek maximális számának számát, szükség szerint átküldheti a fájlokat az átnevezéshez. A kód következő kódrészlete ismét átkerül a fájllistára, és szükség szerint betömi őket. Egy másik reguláris kifejezésmintát használ, amely csak a maximálisnál kisebb számszámú fájlokat dolgozza fel.

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

A fájlok átnevezése után újra lekérheti a fájlok listáját, és név szerint rendezheti a régi és az új fájlokat is. Az alábbi kódrészlet ismét lekéri a fájlokat egy új tömbbe való mentéshez, és összehasonlítja a kezdeti objektumkészlettel. Ezután rendezi a fájltömböket, és menti a rendezett tömböket az új változókba $sortedOriginal és $sortedPadded. Végül egy for hurkot használ a tömbök iterálásához, és a következő tulajdonságokkal rendelkező objektumot ad ki:

  • Index a rendezett tömbök aktuális indexét jelöli.
  • Eredeti az aktuális index eredeti fájlneveinek rendezett tömbjében található elem.
  • a kipárnázott az aktuális indexben lévő párnázott fájlnevek rendezett tömbjének eleme.
$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

A kimenetben a kitöltés utáni rendezett munkaelemek a várt sorrendben vannak.

Lásd még