Szukaj…
Wprowadzenie
Pętla jest sekwencją instrukcji, która jest ciągle powtarzana aż do osiągnięcia określonego warunku. Możliwość wielokrotnego wykonywania bloku kodu przez program jest jednym z najbardziej podstawowych, ale przydatnych zadań w programowaniu. Pętla pozwala napisać bardzo prostą instrukcję, aby uzyskać znacznie lepszy wynik po prostu przez powtórzenie. Jeśli warunek został osiągnięty, następna instrukcja „przechodzi” do następnej instrukcji sekwencyjnej lub rozgałęzia poza pętlą.
Składnia
for (<Inicjalizacja>; <Warunek>; <Repetycja>) {<Script_Block>}
<Kolekcja> | Foreach-Object {<Script_Block_with _ $ __ as_current_item>}
foreach (<Item> w <Collection>) {<Script_Block>}
while (<Warunek>) {<Script_Block>}
do {<Script_Block>} podczas gdy (<Warunek>)
do {<Script_Block>} do (<Warunek>)
<Kolekcja> .foreach ({<Script_Block_with _ $ __ as_current_item>})
Uwagi
Dla każdego
Istnieje wiele sposobów uruchamiania pętli foreach w PowerShell i wszystkie one mają swoje zalety i wady:
Rozwiązanie | Zalety | Niedogodności |
---|---|---|
Oświadczenie Foreach | Najszybszy. Działa najlepiej z kolekcjami statycznymi (przechowywanymi w zmiennej). | Brak wejścia lub wyjścia z potoku |
Metoda ForEach () | Taka sama składnia skryptu jak Foreach-Object , ale szybciej. Działa najlepiej z kolekcjami statycznymi (przechowywanymi w zmiennej). Obsługuje wyjście potoku. | Brak obsługi wprowadzania potokowego. Wymaga programu PowerShell 4.0 lub nowszego |
Foreach-Object (cmdlet) | Obsługuje wejście i wyjście potoku. Obsługuje bloki rozpoczęcia i zakończenia skryptów do inicjowania i zamykania połączeń itp. Najbardziej elastyczne rozwiązanie. | Najwolniejszy |
Występ
$foreach = Measure-Command { foreach ($i in (1..1000000)) { $i * $i } }
$foreachmethod = Measure-Command { (1..1000000).ForEach{ $_ * $_ } }
$foreachobject = Measure-Command { (1..1000000) | ForEach-Object { $_ * $_ } }
"Foreach: $($foreach.TotalSeconds)"
"Foreach method: $($foreachmethod.TotalSeconds)"
"ForEach-Object: $($foreachobject.TotalSeconds)"
Example output:
Foreach: 1.9039875
Foreach method: 4.7559563
ForEach-Object: 10.7543821
Chociaż Foreach-Object
jest najwolniejszy, to jego obsługa potokowa może być przydatna, ponieważ pozwala przetwarzać elementy po ich otrzymaniu (podczas czytania pliku, odbierania danych itp.). Może to być bardzo przydatne podczas pracy z dużymi danymi i małą ilością pamięci, ponieważ nie trzeba ładować wszystkich danych do pamięci przed przetwarzaniem.
Dla
for($i = 0; $i -le 5; $i++){
"$i"
}
Typowym zastosowaniem pętli for jest działanie na podzbiorze wartości w tablicy. W większości przypadków, jeśli chcesz iterować wszystkie wartości w tablicy, rozważ użycie instrukcji foreach.
Dla każdego
ForEach
ma dwa różne znaczenia w PowerShell. Jedno to słowo kluczowe, a drugie to alias polecenia cmdlet ForEach-Object . Pierwsza została opisana tutaj.
W tym przykładzie pokazano drukowanie wszystkich elementów w tablicy na hoście konsoli:
$Names = @('Amy', 'Bob', 'Celine', 'David')
ForEach ($Name in $Names)
{
Write-Host "Hi, my name is $Name!"
}
W tym przykładzie pokazano przechwytywanie wyników pętli ForEach:
$Numbers = ForEach ($Number in 1..20) {
$Number # Alternatively, Write-Output $Number
}
Podobnie jak w poprzednim przykładzie, w tym przykładzie pokazano tworzenie tablicy przed zapisaniem pętli:
$Numbers = @()
ForEach ($Number in 1..20)
{
$Numbers += $Number
}
Podczas
Pętla while oceni warunek i jeśli true wykona akcję. Dopóki warunek zostanie spełniony, działanie będzie kontynuowane.
while(condition){
code_block
}
Poniższy przykład tworzy pętlę, która będzie odliczać od 10 do 0
$i = 10
while($i -ge 0){
$i
$i--
}
W przeciwieństwie do pętli Do
Whil warunek jest oceniany przed pierwszym wykonaniem akcji. Akcja nie zostanie wykonana, jeśli warunek początkowy zostanie oceniony na false.
Uwaga: Podczas oceny warunku, PowerShell potraktuje istnienie zwracanego obiektu jako prawdziwe. Można to wykorzystać na kilka sposobów, ale poniżej znajduje się przykład monitorowania procesu. Ten przykład spowoduje odrodzenie procesu notatnika, a następnie uśpienie bieżącej powłoki, dopóki ten proces będzie działał. Po ręcznym zamknięciu instancji notatnika warunek while nie powiedzie się, a pętla zostanie przerwana.
Start-Process notepad.exe
while(Get-Process notepad -ErrorAction SilentlyContinue){
Start-Sleep -Milliseconds 500
}
ForEach-Object
ForEach-Object
cmdlet ForEach-Object
działa podobnie do instrukcji foreach
, ale pobiera dane wejściowe z potoku.
Podstawowe użycie
$object | ForEach-Object {
code_block
}
Przykład:
$names = @("Any","Bob","Celine","David")
$names | ForEach-Object {
"Hi, my name is $_!"
}
Foreach-Object
ma dwa domyślne aliasy: foreach
i %
(skrócona składnia). Najczęściej jest to %
ponieważ foreach
można pomylić z instrukcją foreach . Przykłady:
$names | % {
"Hi, my name is $_!"
}
$names | foreach {
"Hi, my name is $_!"
}
Zaawansowane użycie
Foreach-Object
wyróżnia się spośród alternatywnych rozwiązań foreach
, ponieważ jest to cmdlet, co oznacza, że został zaprojektowany do korzystania z potoku. Z tego powodu obsługuje trzy bloki skryptowe, takie jak polecenie cmdlet lub funkcja zaawansowana:
- Rozpocznij : Wykonane raz, zanim przejdzie przez elementy przychodzące z potoku. Zwykle służy do tworzenia funkcji do użytku w pętli, tworzenia zmiennych, otwierania połączeń (baza danych, web +) itp.
- Proces : wykonywany raz dla każdego elementu przybywającego z potoku. „Normalny” blok kodu. Jest to ustawienie domyślne używane w powyższych przykładach, gdy parametr nie jest określony.
- Koniec : Wykonane raz po przetworzeniu wszystkich elementów. Zwykle służy do zamykania połączeń, generowania raportu itp.
Przykład:
"Any","Bob","Celine","David" | ForEach-Object -Begin {
$results = @()
} -Process {
#Create and store message
$results += "Hi, my name is $_!"
} -End {
#Count messages and output
Write-Host "Total messages: $($results.Count)"
$results
}
Robić
Pętle do są przydatne, gdy zawsze chcesz uruchomić kodowanie przynajmniej raz. Pętla Do ocenia stan po wykonaniu kodu, w przeciwieństwie do pętli while, która robi to przed wykonaniem kodu.
Pętli do można używać na dwa sposoby:
Pętla, gdy warunek jest spełniony:
Do { code_block } while (condition)
Zapętlaj dopóki warunek nie będzie prawdziwy, innymi słowy zapętlaj dopóki warunek jest fałszywy:
Do { code_block } until (condition)
Prawdziwe przykłady:
$i = 0
Do {
$i++
"Number $i"
} while ($i -ne 3)
Do {
$i++
"Number $i"
} until ($i -eq 3)
Do-While i Do-Until są antonimicznymi pętlami. Jeśli kod w tym samym, warunek zostanie odwrócony. Powyższy przykład ilustruje to zachowanie.
Metoda ForEach ()
Zamiast ForEach-Object
, tutaj jest również możliwość użycia metody ForEach
bezpośrednio na tablicach obiektów takich jak
(1..10).ForEach({$_ * $_})
lub - w razie potrzeby - można pominąć nawiasy wokół bloku skryptu
(1..10).ForEach{$_ * $_}
Oba spowodują wynik poniżej
1
4
9
16
25
36
49
64
81
100
Kontyntynuj
Operator Continue
działa w ForEach
For
, ForEach
, While
i Do
Pomija bieżącą iterację pętli, przeskakując na szczyt najbardziej wewnętrznej pętli.
$i =0
while ($i -lt 20) {
$i++
if ($i -eq 7) { continue }
Write-Host $I
}
Powyższe spowoduje wyświetlenie od 1 do 20 na konsoli, ale przegap liczbę 7.
Uwaga : Korzystając z pętli potokowej, powinieneś użyć return
zamiast Continue
.
Przerwa
Operator break
natychmiast wyjdzie z pętli programu. Można go używać w ForEach
For
, ForEach
, While
i Do
lub w instrukcji Switch
.
$i = 0
while ($i -lt 15) {
$i++
if ($i -eq 7) {break}
Write-Host $i
}
Powyższe liczy się do 15, ale zatrzyma się, gdy tylko osiągnie 7.
Uwaga : W przypadku korzystania z pętli potokowej break
będzie się zachowywać jak continue
. Aby zasymulować break
w pętli potoku, należy wprowadzić dodatkową logikę, polecenie cmdlet itp. Łatwiej jest trzymać się pętli niepotokowych, jeśli trzeba użyć break
.
Rozbij etykiety
Break może również wywołać etykietę umieszczoną przed wystąpieniem pętli:
$i = 0
:mainLoop While ($i -lt 15) {
Write-Host $i -ForegroundColor 'Cyan'
$j = 0
While ($j -lt 15) {
Write-Host $j -ForegroundColor 'Magenta'
$k = $i*$j
Write-Host $k -ForegroundColor 'Green'
if ($k -gt 100) {
break mainLoop
}
$j++
}
$i++
}
Uwaga: Ten kod zwiększy $i
do 8
i $j
do 13
co spowoduje, że $k
104
. Ponieważ $k
przekracza 100
, kod wyrwie się z obu pętli.