我已经在同一主题上看过别人的question and answer,但对我来说,它没有回答这个问题。
我知道如何使用Select-Object,Where-Object,ForEach-Object等并传递脚本块,例如:
dir | ForEach-Object { $_.Name }
返回当前目录中所有文件名的数组。
这类似于C#的Select扩展方法:
Dir.Select(x => x.Name)
但是,上面的C#很容易理解,因为我们将一个函数传递给Select方法,然后Select方法为列表中的每个元素执行它。
但是,PowerShell中的等价物:
dir | ForEach-Object { param($x) $x.Name }
不会返回任何内容。然而
& { param($x) $x.Name } (dir)[0]
按预期工作。
有人可以向C#熟悉的人解释$ _的神奇之处,但不能解释脚本世界吗?这是一个特殊的关键字?它是否只能用于传递给cmdlet的脚本块?如何在不使用ForEach-Object(或任何其他cmdlet)的情况下调用一个?即:
& { $_.Name } (dir)[0]
答案 0 :(得分:9)
$_
仅在管道的上下文中创建,即将输出对象从一个命令传递到另一个命令的“输入”。对于管道过滤器(类似于函数),powershell会自动使用管道的当前对象填充$_
变量。现在我说当前是因为重要的是要注意当多个对象沿管道传递时,过滤器的进程脚本块每个对象执行一次。
现在,您可以将管道对象重命名为其中一个输入参数,但您必须告诉powershell您正在这样做。例如:
# C:\> filter get-name-filt {Param([parameter(ValueFromPipeline=$true)]$x) $x.name}
# C:\> (dir)[0] | get-name-filt
在命令行上不是非常方便,因此是$ _自动变量。
答案 1 :(得分:4)
$_
是当前的管道项。
例如:
dir | ForEach-Object { $_.Name }
意思是:
由于dir
的输出具有属性.name
,因此流水线$_
也将具有相同的属性。它只是一种沿管道传递数据的方法