如何在PowerShell中使用foreach管道输出

3

我尝试将foreach循环的输出导入格式命令,但它不起作用。我认为可能的原因是因为这个可以工作。

$op = foreach ($file in (Get-ChildItem -File)) {
    $file |
    Get-Member |
    Where-Object {$_.MemberType -eq "Method" -and $_.Definition -like "*system*" } |
    Select-Object -Property Name, MemberType
}

$op | Format-List

如果我可以将整个输出分配给一个变量,并将该变量管道传递到另一个命令中,为什么以下命令不起作用?
(foreach ($file in (Get-ChildItem -File)) {
    $file |
    Get-Member |
    Where-Object {$_.MemberType -eq "Method" -and $_.Definition -like "*system*" } |
    Select-Object -Property Name, MemberType
}) | Format-List

当然,我尝试过没有括号,但最终我认为如果有括号反而更好理解。就像$file in (Get-ChildItem -File)一样,在括号内求值并将结果作为实际对象使用。
有方法使这个工作吗?
请注意,该代码不应该完成除演示机制以外的任何其他操作。

1
PowerShell区分命令解析模式和表达式解析模式 - 你同时涉及到了这两种情况... - Peter Schneider
1
如果你使用 $(foreach ...),它会起作用。 - Maximilian Burszley
1
我不知道$()() 之间的确切原因或区别。我以前在这个标签中问过问题,但没有人能给我一个简明扼要的答案。我只知道将东西包装在子表达式中会导致它们以不同的方式输出。 - Maximilian Burszley
2
这里有解释:链接 - Peter Schneider
@PeterSchneider 很棒。你的谷歌功夫比我强大。 - Maximilian Burszley
2个回答

2

foreach没有你可以捕获的输出(除了你通过变量赋值找到的语法糖),但是你可以通过将其包装在子表达式中来收集由它返回的所有对象:

$(foreach ($file in Get-ChildItem -File) {
    # ...
}) | Format-List

同样的模式也可以用于ifswitch语句。


2

以下是另一种方法,无需等待整个foreach完成。这就像即时定义函数:

& { foreach ($file in Get-ChildItem -File) {
      $file |
      Get-Member |
      Where-Object {$_.MemberType -eq "Method" -and $_.Definition -like "*system*" } |
      Select-Object -Property Name, MemberType
    } 
} | format-list

顺便一提,$( ) 可以放在 ( ) 能放的任何地方,但它可以包含多个通过换行符或分号分隔的语句。

另外,你还可以直接进行管道传递:

Get-ChildItem -File |
Get-Member |
Where-Object {$_.MemberType -eq "Method" -and $_.Definition -like "*system*" } |
Select-Object -Property Name, MemberType | 
Format-List

啊,很好的使用了IIFE。忘记你可以这样做了。它只是多了创建新作用域和管理调用的额外开销。 - Maximilian Burszley
好的,很棒!我知道这个技巧,但有点不同。1..3 | & {Process { $_*3 }} 现在有意义了。昨天我学到,默认情况下函数会使用结束块。这就是为什么在我的例子中我需要显式地使用 process,但当你使用它时,结束块是正确的,并且返回可管道的结果。但为什么它不需要等待 foreach 完成呢? - The Fool
我不知道为什么。我只知道它确实这样做。 - js2010
1
@TheFool 管道和脚本块黑魔法;它不像子表达式一样被视为单个命令。 - Maximilian Burszley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接