Co oznacza $ _ w PowerShell?

226

Wiele razy widziałem w PowerShell, ale co to dokładnie robi?

$_
Micheasz
źródło
5
Odpowiedzi na pytanie oczywiście udzielił pojedynczy podany token specjalny, ale w przypadku schematu ściennego ilustrującego wszystkie specjalne tokeny PowerShell, spójrz na Kompletny przewodnik po interpunkcji PowerShell
Michael Sorens

Odpowiedzi:

171

Jest to zmienna dla bieżącej wartości w rurociągu, która jest wywoływana $PSItemw Powershell 3 i nowszych.

1,2,3 | %{ write-host $_ } 

lub

1,2,3 | %{ write-host $PSItem } 

Na przykład w powyższym kodzie %{}blok jest wywoływany dla każdej wartości w tablicy. $_Czy $PSItemzmienna zawiera aktualną wartość.

JaredPar
źródło
42
Nie musi to być związane z rurociągiem. To bardziej „aktualny argument do aktualnie wykonywanego bloku skryptu”. Na przykład, kiedy możesz go używać dobrze ForEach-Objectlub Where-Objectnie możesz użyć go w czymś takim Get-Foo|Add-Member NoteProperty Bar ($_.SomeProperty)- jest zaangażowany potok, ale nie ma bloku skryptu, a zatem nie $_. (To powiedziawszy, pomoc PowerShell odnosi się również do potoku $_. Mylące.)
Joey
@Joey, możesz absolutnie użyć $ _ w swoim przykładzie. Get-Foo | Add-Member -Type NoteProperty -Name Bar -Value $_.SomeProperty
Xalorous,
@Xalorous: To, że nie powoduje błędu, nie oznacza, że ​​działa: Get-ChildItem | Add-Member -Type NoteProperty -Name Bar -Value $_.Name -PassThru | Select Bar... Cóż, może działać, jeśli masz $_zakres, w którym wykonujesz ten potok. Ale to bardzo różni się od tego, co zwykle masz na myśli, gdy piszesz coś takiego.
Joey,
@Joey $_w tym, co napisałeś, z jakiegoś powodu nie zapętla wszystkich obiektów. Spróbuj tego zamiast tego. gci | % { $_ | add-member -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar. Podejrzewam, że posiadanie gci | cmdletbez jawnego foreach zbiera wyniki gci i przekazuje tablicę do cmdletu. Jednak tablica jest obiektem, więc dodaje właściwość do obiektu tablicy. Tablica nie ma właściwości „name”, więc wartość przypisana do $ _. Pasek ma wartość $ null. Najważniejsze jest to, że $ _ jest szeroko stosowane w / potokach. Nie potrzeba% {} do przejścia przez pętlę jest nowy.
Xalorous,
Wersja robocza z usuniętym dodatkowym potokiem. gci | % { add-member -InputObject $_ -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar
Xalorous,
37

Myślę, że najłatwiejszym sposobem myślenia o tej zmiennej jest parametr wejściowy w wyrażeniu lambda w języku C #. Czyli $_jest podobny do xw x => Console.WriteLine(x)anonimowej funkcji w języku C #. Rozważ następujące przykłady:

PowerShell:

1,2,3 | ForEach-Object {Write-Host $_}

Wydruki:

1
2
3

lub

1,2,3 | Where-Object {$_ -gt 1}

Wydruki:

2
3

I porównaj to ze składnią C # za pomocą LINQ:

var list = new List<int> { 1, 2, 3 };
list.ForEach( _ => Console.WriteLine( _ ));

Wydruki:

1
2
3

lub

list.Where( _ => _ > 1)
    .ToList()
    .ForEach(s => Console.WriteLine(s));

Wydruki:

2
3
Siergiej Cieplakow
źródło
6
W C # nie używaj _jako parametru wejściowego w lambda. _jest czasami używany, gdy parametry są ignorowane, zamiast tego użyj x. stackoverflow.com/questions/424775/…
Carlos Muñoz
28

Według tej witryny jest to odniesienie this, głównie w pętlach.

$ _ (podkreślenie dolara) token „TO”. Zazwyczaj odnosi się do przedmiotu w pętli foreach. Zadanie: wydrukuj wszystkie elementy w kolekcji. Rozwiązanie. ... | foreach {Write-Host $ _}

Ikke
źródło
3
thisjest raczej mylącym terminem dla $_zmiennej. W OOP zwykle odnosi się do klasy, a nie do zmiennej.
o
1
@remco, zwłaszcza gdy PS v5 dodaje zmienną $ $ do użycia w klasach.
Xalorous,
5

$ _ to alias dla automatycznej zmiennej $ PSItem (wprowadzony w PowerShell V3.0; informacje o użyciu można znaleźć tutaj ), która reprezentuje bieżący element z potoku.

Dokumentacja online programu PowerShell (wersja 6.0) dla zmiennych automatycznych znajduje się tutaj .

Xalorous
źródło
1

$ _ jest zmienną, która iteruje każdy obiekt / element przekazany z poprzedniego | (rura).

Rachunek
źródło
1

$_jest zmienną utworzoną przez system, zwykle wewnątrz wyrażeń blokowych, do których odwołują się polecenia cmdlet używane z potokiem, takim jak Where-ObjectiForEach-Object .

Ale można go również stosować w innych typach wyrażeń, na przykład w Select-Objectpołączeniu z właściwościami wyrażeń. Get-ChildItem | Select-Object @{Name="Name";Expression={$_.Name}}. W tym przypadku$_ reprezentuje przesyłany element, ale może istnieć wiele wyrażeń.

Można się do niego odwoływać również poprzez niestandardowe sprawdzanie poprawności parametrów, gdzie blok skryptu służy do sprawdzania poprawności wartości. W tym przypadku $_reprezentuje wartość parametru otrzymaną z wywołania.

Najbliższą analogią do c # i java jest wyrażenie lamda. Jeśli podzielisz PowerShell na podstawy, wszystko to blok skryptu, w tym plik skryptu a, funkcje i polecenia cmdlet. Możesz zdefiniować własne parametry, ale w niektórych przypadkach system tworzy taki, który reprezentuje element wejściowy do przetworzenia / oceny . W takich sytuacjach zmienną automatyczną jest $_.

Alex Sarafian
źródło