2017-02-24 117 views
1

我使用PowerShell 5,如果这是相关的PowerShell:管道物体进入管道对象

当管道中添加一个属性到当前项目:

我不能引用$ _直到我把它喂进另一个管道。 为什么?

# make some objects to pass around 
$test = (0..3) | %{[pscustomobject]@{key1="v$_.1";key2="v$_.2"} } 
# GM = TypeName: System.Management.Automation.PSCustomObject 
# trying to use the current pipeline object 
$test | Add-Member @{key3=$_.key1} 
$test | ft * 

key1 key2 key3 
---- ---- ---- 
v0.1 v0.2  
v1.1 v1.2  
v2.1 v2.2  
v3.1 v3.2  

# try again, this time taking the current pipeline object... 
#... and then putting it into another identical looking pipeline 
$test | %{ $_ | Add-Member @{key4=$_.key1} } 
$test | ft * 

key1 key2 key3 key4 
---- ---- ---- ---- 
v0.1 v0.2  v0.1 
v1.1 v1.2  v1.1 
v2.1 v2.2  v2.1 
v3.1 v3.2  v3.1 

我怀疑这可能是第一个将自动意味着什么,我还没有告诉无形/隐含功能转嫁$ PSItem。

+0

在管道启动之前评估所有参数。 '[pscustomobject] @ {key1 ='其他'} | %{$ test | Add-Member @ {key3 = $ _。key1}}'。 – PetSerAl

回答

3

在命令开始之前,所有参数在当前scope中进行评估,无论在流水线中是否使用语法。因此$test | Add-Member @{key3=$_.key1}使用当前范围内的$_,这意味着它不是$test中的元素。

要使$_评价管道中的每个元件,一个新的范围应被用于经由脚本块的每个元素(在大括号中的代码)在ForEach创建,Where1..2 | ForEach { $_ },或在脚本块参数如在select @{N='calculated property'; E={$_.foo}}E上的表达。

+1

你称之为_context_通常被命名为_scope_。脚本块会打开一个新的作用域,其中可以定义外部作用域中不存在的变量。 – Joey

+0

的确,谢谢,我已经编辑了答案。 – wOxxOm