Was bedeutet $ _ in PowerShell?

226

Ich habe in PowerShell viel Folgendes gesehen, aber was macht es genau?

$_
Micah
quelle
5
Die Frage wurde natürlich für das einzelne gegebene spezielle Token beantwortet, aber für ein Wallchart, das alle speziellen Token von PowerShell veranschaulicht , werfen Sie einen Blick auf den vollständigen Leitfaden zur PowerShell-Interpunktion
Michael Sorens,

Antworten:

171

Dies ist die Variable für den aktuellen Wert in der Rohrleitung, die $PSItemin Powershell 3 und höher aufgerufen wird .

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

oder

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

Im obigen Code wird der %{}Block beispielsweise für jeden Wert im Array aufgerufen. Die Variable $_oder $PSItementhält den aktuellen Wert.

JaredPar
quelle
42
Es hängt nicht unbedingt mit der Pipeline zusammen. Es ist eher ein "aktuelles Argument für den aktuell ausgeführten Skriptblock". Zum Beispiel, während Sie es gut in verwenden können ForEach-Objectoder Where-ObjectSie können es nicht in so etwas wie verwenden Get-Foo|Add-Member NoteProperty Bar ($_.SomeProperty)- es ist eine Pipeline beteiligt, aber kein Skriptblock und daher nein $_. (Davon abgesehen bezieht sich die PowerShell-Hilfe auch auf die Pipeline für $_. Verwirrend.)
Joey
@Joey Sie können absolut $ _ in Ihrem Beispiel verwenden. Get-Foo | Add-Member -Type NoteProperty -Name Bar -Value $_.SomeProperty
Xalorous
@Xalorous: Nur weil es keinen Fehler erzeugt, heißt das nicht, dass es funktioniert: Get-ChildItem | Add-Member -Type NoteProperty -Name Bar -Value $_.Name -PassThru | Select Bar... Nun, es kann funktionieren, wenn Sie eine $_in dem Bereich haben, in dem Sie diese Pipeline ausführen. Aber das unterscheidet sich sehr von dem, was Sie normalerweise meinen, wenn Sie versuchen, so etwas zu schreiben.
Joey
@Joey $_in dem, was Sie geschrieben haben, durchläuft aus irgendeinem Grund nicht alle Objekte. Versuchen Sie dies stattdessen. gci | % { $_ | add-member -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar. Ich vermute, dass gci | cmdletohne das explizite foreach gci-Ergebnisse gesammelt und ein Array an das Cmdlet übergeben werden. Da das Array jedoch ein Objekt ist, wird dem Array-Objekt eine Eigenschaft hinzugefügt. Das Array hat keine 'name'-Eigenschaft, daher ist der Wert, der $ _. Bar zugewiesen wird, $ null. Fazit ist, dass $ _ häufig mit Pipelining verwendet wird. Es ist neu,% {} nicht zum Durchlaufen zu benötigen.
Xalorous
Arbeitsversion mit entfernter zusätzlicher Pipeline. gci | % { add-member -InputObject $_ -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar
Xalorous
37

Ich denke, der einfachste Weg, über diese Variable wie den Eingabeparameter im Lambda-Ausdruck in C # nachzudenken. Dh $_ist ähnlich wie xinx => Console.WriteLine(x) anonymer Funktion in C #. Betrachten Sie folgende Beispiele:

Power Shell:

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

Drucke:

1
2
3

oder

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

Drucke:

2
3

Und vergleichen Sie dies mit der C # -Syntax unter Verwendung von LINQ:

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

Drucke:

1
2
3

oder

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

Drucke:

2
3
Sergey Teplyakov
quelle
6
In C # nicht _als Eingabeparameter in Lambda verwenden. _wird manchmal verwendet, wenn die Parameter ignoriert werden. Verwenden Sie stattdessen x. stackoverflow.com/questions/424775/…
Carlos Muñoz
28

Laut dieser Website handelt es sich um einen Verweis this, meist in Schleifen.

$ _ (Dollar-Unterstrich) 'DIESES' Token. Bezieht sich normalerweise auf das Element innerhalb einer foreach-Schleife. Aufgabe: Drucken Sie alle Elemente in einer Sammlung. Lösung. ... | foreach {Write-Host $ _}

Ikke
quelle
3
thisist ein ziemlich verwirrender Begriff für die $_Variable. In OOP bezieht es sich normalerweise auf die Klasse, nicht auf eine Variable.
6.
1
@remco, insbesondere wenn PS v5 eine Variable $ this zur Verwendung in Klassen hinzufügt.
Xalorous
5

$ _ ist ein Alias ​​für die automatische Variable $ PSItem (eingeführt in PowerShell V3.0; hier verwendete Verwendungsinformationen ), der das aktuelle Element aus der Pipe darstellt.

Die Online-Dokumentation zu PowerShell (v6.0) für automatische Variablen finden Sie hier .

Xalorous
quelle
1

$ _ ist eine Variable, die über jedes Objekt / Element iteriert, das vom vorherigen | übergeben wurde (Rohr).

Rechnung
quelle
1

$_ist eine Variable, die vom System normalerweise in Blockausdrücken erstellt wird, auf die von Cmdlets verwiesen wird, die mit Pipe wie Where-Objectund verwendet werden ForEach-Object.

Es kann aber auch in anderen Arten von Ausdrücken verwendet werden, beispielsweise in Select-ObjectKombination mit Ausdruckseigenschaften. Get-ChildItem | Select-Object @{Name="Name";Expression={$_.Name}}. In diesem Fall $_stellt das das Element dar, das weitergeleitet wird, es können jedoch mehrere Ausdrücke vorhanden sein.

Es kann auch durch benutzerdefinierte Parameterüberprüfung referenziert werden, wobei ein Skriptblock zum Überprüfen eines Werts verwendet wird. In diesem Fall $_repräsentiert der den Parameterwert, wie er vom Aufruf empfangen wurde.

Die nächste Analogie zu c # und Java ist der Lamda-Ausdruck. Wenn Sie Powershell in Grundlagen zerlegen, ist alles ein Skriptblock, einschließlich einer Skriptdatei a, Funktionen und Cmdlets. Sie können Ihre eigenen Parameter definieren, aber in einigen Fällen wird vom System einer für Sie erstellt, der das zu verarbeitende / auszuwertende Eingabeelement darstellt . In diesen Situationen ist die automatische Variable $_.

Alex Sarafian
quelle