foreach în PowerShell

Control și funcții Windows PowerShell 1.0

Buclele foreach, for, while și do-while repetă un bloc de cod; foreach parcurge o colecție din memorie, ForEach-Object lucrează în pipeline.

Sintaxă
foreach ($element in $colectie) { ... }
for ($i = 0; $i -lt 10; $i++) { ... }
while (<condiție>) { ... }
do { ... } while (<condiție>)

Ce face foreach

foreach ($oras in $orase) { ... } parcurge pe rând elementele unei colecții, punând fiecare element în variabila aleasă. Colecția poate fi și rezultatul unei comenzi: foreach ($f in Get-ChildItem) { ... }. break iese din buclă, continue sare la elementul următor. Rezultatul unei bucle se poate atribui direct: $patrate = foreach ($n in 1..5) { $n * $n }.

for ($i = 0; $i -lt 10; $i++) e bucla cu contor, utilă când ai nevoie de index. while (cond) { } repetă cât timp condiția e adevărată și poate să nu ruleze deloc. do { } while (cond) rulează blocul cel puțin o dată și verifică la final; do { } until (cond) repetă până când condiția devine adevărată.

Instrucțiunea foreach nu este același lucru cu cmdlet-ul ForEach-Object, chiar dacă foreach este și alias pentru el când apare după |. Instrucțiunea strânge întâi toată colecția în memorie și apoi o parcurge, de obicei mai repede; ForEach-Object primește obiectele unul câte unul prin pipeline, cu obiectul curent în $_, și e potrivit pentru fluxuri mari sau când vrei să continui pipeline-ul. Paralelismul (-Parallel, din PowerShell 7.0) există doar la ForEach-Object.

Parametri

Parametru Descriere
foreach ($x in $c) { } Parcurge fiecare element din $c.
for (init; cond; pas) { } Buclă cu contor.
while (cond) { } Repetă cât timp condiția e adevărată (verificare la început).
do { } while (cond) Rulează cel puțin o dată; repetă cât timp condiția e adevărată.
do { } until (cond) Rulează cel puțin o dată; repetă până când condiția devine adevărată.
break / continue Ieși din buclă / treci la pasul următor.

Exemple

Exemplul 1: Parcurgi o listă de orașe

Variabila $oras primește pe rând fiecare element.

$orase = 'Iași', 'Cluj', 'Timișoara'
foreach ($oras in $orase) {
    "$oras are $($oras.Length) litere"
}

Ieșire în terminal

Iași are 4 litere
Cluj are 4 litere
Timișoara are 9 litere

Exemplul 2: for, while și do-while

Bucla for numără rândurile, while face două încercări, iar do-while scade contorul până la zero.

for ($i = 1; $i -le 2; $i++) {
    "Rândul $i"
}
$incercari = 0
while ($incercari -lt 2) {
    $incercari++
    "Încercarea $incercari"
}
do {
    $incercari--
} while ($incercari -gt 0)
"Final: $incercari"

Ieșire în terminal

Rândul 1
Rândul 2
Încercarea 1
Încercarea 2
Final: 0

Exemplul 3: Instrucțiunea foreach și cmdlet-ul ForEach-Object

Același rezultat: instrucțiunea folosește variabila ta, cmdlet-ul din pipeline folosește $_.

foreach ($n in 1..3) { $n * 2 }
1..3 | ForEach-Object { $_ * 2 }

Ieșire în terminal

2
4
6
2
4
6

Greșeli frecvente

  • Să folosești $_ în instrucțiunea foreach: acolo obiectul curent este variabila declarată ($oras), nu $_.
  • Să scrii Get-ChildItem | foreach ($f in ...): după |, foreach este alias pentru ForEach-Object și primește un bloc { }, nu sintaxa cu in.
  • Să uiți să modifici variabila din condiția lui while: bucla nu se mai oprește. Oprești o buclă blocată cu Ctrl+C.
  • Să folosești break în blocul lui ForEach-Object crezând că oprește doar cmdlet-ul: break nu este pentru pipeline și poate opri și codul din jur. În pipeline filtrează cu Where-Object sau oprește-te cu Select-Object -First.

Comenzi înrudite

  • ForEach-Object: Rulează un bloc de cod pentru fiecare obiect din pipeline; din PowerShell 7.0 poate rula blocurile în paralel cu -Parallel.
  • Tablouri (@()): Un tablou ține mai multe valori; îl creezi cu virgule sau @(), îl citești cu [index], iar += creează de fiecare dată un tablou nou.
  • switch: switch compară o valoare (sau fiecare element al unei colecții) cu mai multe modele și rulează blocul celor potrivite; are -Wildcard și -Regex.
  • if / elseif / else: if rulează un bloc de cod doar când condiția e adevărată; elseif și else tratează celelalte cazuri, iar ?: (din PowerShell 7.0) e forma scurtă.
  • Where-Object: Filtrează obiectele din pipeline și le lasă să treacă doar pe cele care îndeplinesc o condiție.