$ _在PowerShell中是什么意思?


Answers:


171

这是管道中当前值的变量,$PSItem在Powershell 3及更高版本中称为该变量。

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

要么

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

例如,在上面的代码中,%{}将为数组中的每个值调用该块。的$_$PSItem可变的将包含当前值。


42
它不一定与管道有关。它更多是“当前正在执行的脚本块的当前参数”。例如当你可以使用它只是罚款ForEach-Object或者Where-Object就像你不能在一些使用它Get-Foo|Add-Member NoteProperty Bar ($_.SomeProperty)-有一个管道参与,但没有脚本块,因此没有$_。(话虽如此,PowerShell帮助也指向$_。令人困惑的管道。)
Joey

@Joey您可以在示例中绝对使用$ _。Get-Foo | Add-Member -Type NoteProperty -Name Bar -Value $_.SomeProperty
Xalorous 2015年

@Xalorous:仅仅因为它不会产生错误并不意味着它会工作:Get-ChildItem | Add-Member -Type NoteProperty -Name Bar -Value $_.Name -PassThru | Select Bar...好吧,如果您在执行该管道的范围内有一个,它就可以工作$_。但这与您尝试编写类似内容的通常含义大不相同。
乔伊

$_由于某种原因,@ Joey 编写的内容不会遍历所有对象。试试这个吧。 gci | % { $_ | add-member -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar。我怀疑gci | cmdlet没有显式的foreach会收集gci结果并将数组传递给cmdlet。但是,数组是一个对象,因此它向数组对象添加了一个属性。该数组没有'name'属性,因此分配给$ _。Bar的值为$ null。底线是$ _广泛用于流水线。不需要%{}来遍历是新的。
Xalorous 2015年

工作版本,删除了多余的管道。 gci | % { add-member -InputObject $_ -Type NoteProperty -Name Bar -Value $_.name -PassThru } | Select Bar
Xalorous 2015年

37

我认为最简单的方法来考虑此变量,例如C#中的lambda表达式中的输入参数。即$_类似于C#x中的x => Console.WriteLine(x)匿名函数。考虑以下示例:

电源外壳:

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

印刷品:

1
2
3

要么

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

印刷品:

2
3

并将其与使用LINQ的C#语法进行比较:

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

印刷品:

1
2
3

要么

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

印刷品:

2
3

6
在C#中,请勿_在lambda中用作输入参数。_有时在忽略参数时使用,请改用x。stackoverflow.com/questions/424775/...
卡洛斯·穆尼奥斯

28

根据网站的说法,它this主要是循环引用。

$ _(美元下划线)“ THIS”令牌。通常是指foreach循环内的项目。任务:打印集合中的所有项目。解。... | foreach {写主机$ _}


3
this$_变量的相当混乱的术语。在OOP中,它通常是指类,而不是变量。
oɔɯǝɹ

1
@remco,尤其是当PS v5添加$ this变量在类中使用时。
Xalorous


1

$ _是一个变量,它迭代从上一个|传递的每个对象/元素。(管)。


1

$_是系统通常在块表达式中创建的变量,该块表达式由与管道(例如Where-Object和)一起使用的cmdlet引用ForEach-Object

但是它也可以用于其他类型的表达式中,例如Select-Object与表达式属性结合使用。Get-ChildItem | Select-Object @{Name="Name";Expression={$_.Name}}。在这种情况下$_表示正在传递的项目,但可以存在多个表达式。

也可以通过自定义参数验证来引用它,其中脚本块用于验证值。在这种情况下,$_代表从调用中接收到的参数值。

与c#和java最接近的类比是lamda表达式。如果将Powershell分解为基本知识,则所有内容都是脚本块,包括脚本文件a,函数和cmdlet。您可以定义自己的参数,但是在某些情况下,系统会为您创建一个代表要处理/评估的输入项的参数。在这种情况下,自动变量为$_

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.