是否可以在不分配给变量的情况下通过管道传递 while 循环的结果 [英] Is it possible to pipe the result of a while loop without assigning to a variable

查看:57
本文介绍了是否可以在不分配给变量的情况下通过管道传递 while 循环的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码无效

$result = (而 ($true) {<#生成psobject的长列表#>}) |Tee-Object -FilePath 'fname.csv' |组-对象-属性 xxx |选择名称,计数

<块引用>

术语while"未被识别为 cmdlet、函数、脚本文件或可运行程序的名称.检查名称的拼写,如果包含路径,请验证路径是否正确,然后重试.

解决方案

虽然:

  • 您可以使用表达式作为管道的第一段(例如,
    1..2 | Tee-Object - 变量结果),

  • 不能使用复合语句,例如ifwhile>、foreachdo 很遗憾.

也就是说,这样的复合语句不是真正的表达式,尽管在​​赋值的上下文中它们可以起到这样的作用.也就是说,您可以执行 $result = while ($true) ... - 无需在 (...) 中包含 while -但是你不能直接通过管道发送while循环.

参见 这个 GitHub 问题,其中讨论了这个有问题的半表达式状态";复合语句,并询问是否可以使它们成为完整的表达式;事实证明,PowerShell 语法的基础阻止了这种情况.

解决方法:

  • 如果你想让你的循环复合语句,即把它的对象一个一个输出到管道,如它们变得可用 - 即,如果您想要标准的流式管道行为:

    • & 包裹你的复合语句{ ... } (或 . { ... },如果您想直接在当前范围内运行而不是在子范围内运行).
    • 例如,&{ foreach ($i in 1..2) { $i } } |Tee-Object - 变量结果
  • 如果您想收集循环复合语句的所有输出预先通过管道发送它们之前:

    • 将复合语句包装在 $(...) 中,子表达式运算符.
    • 例如,$(foreach ($i in 1..2) { $i }) |Tee-Object - 变量结果
    • 注意:
      • 同时使用 $(...) 而不是 &{ ... } 可以加速您的管道,它只是略微加速,并且它可能以内存消耗为代价,因为所有输出总是em> 首先收集到内存中.
      • 这同样适用于 @(...)array-subexpression operator(...)分组运算符,但请注意(...) 仅适用于单个 表达式命令.这个答案对比了(...)$(...)@(...) 详细说明.

适用于您的案例:

$result = &{而 ($true) {<#生成psobject的长列表#>}} |Tee-Object -FilePath 'fname.csv' |...

The following code doesn't work

$result = (
    while ($true) { 
        <# Generating long list of psobject #> 
    }) | Tee-Object -FilePath 'fname.csv' | Group-Object -Property xxx | Select Name,Count

The term 'while' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

解决方案

While:

  • you can use expressions as the first segment of a pipeline (e.g.,
    1..2 | Tee-Object -Variable result),

  • you cannot use compound statements such as if, while, foreach, and do as-is, unfortunately.

That is, such compound statements aren't true expressions, even though in the context of assignments they can act a such. That is, you could do $result = while ($true) ... - without enclosing the while in (...) - yet you cannot send the while loop directly through a pipeline.

See this GitHub issue, which discusses this problematic "half-expression status" of compound statements, and asks if it's feasible to make them full expressions; as it turns out, the fundamentals of PowerShell's grammar prevent that.

Workarounds:

  • If you want your looping compound statement to stream, i.e. to output its objects one by one to the pipeline, as they become available - i.e. if you want the standard, streaming pipeline behavior:

    • Wrap your compound statement in & { ... } (or . { ... }, if you want to run directly in the current rather than in a child scope).
    • E.g., & { foreach ($i in 1..2) { $i } } | Tee-Object -Variable result
  • If you want to collect all outputs from your looping compound statement up front, before sending them through the pipeline:

    • Wrap your compound statement in $(...), the subexpression operator.
    • E.g., $(foreach ($i in 1..2) { $i }) | Tee-Object -Variable result
    • Note:
      • While using $(...) over & { ... } can speed up your pipeline, it does so only slightly, and it potentially comes at the expense of memory consumption, given that all outputs are invariably collected in memory first.
      • The same applies to @(...), the array-subexpression operator and (...), the grouping operator, but note that (...) only works with a single expression or command. This answer contrasts (...), $(...) and @(...) in detail.

Applied to your case:

$result = & {
    while ($true) { 
        <# Generating long list of psobject #> 
    } 
  } | Tee-Object -FilePath 'fname.csv' | ...

这篇关于是否可以在不分配给变量的情况下通过管道传递 while 循环的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆