表达式中的 Powershell 赋值?

Powershell assignment in expression?

Powershell 是否有像 Python 的 := 这样的运算符,它可以在表达式中分配变量? (例如,if (match := pattern.search(data)) is not None
假设我想将一个值作为变量存储在 Powershell 中,但也将它传递到管道中。有没有比...| ForEach-Object { $foo = $_.split(': ')[1]; $foo } |...更优雅的方式?

你可以使用(...)grouping operator把一个赋值语句变成一个表达式,通过正在分配的值 through:

这可以让您简化:

...| ForEach-Object { $foo = $_.split(': ')[1]; $foo }

至:

...| ForEach-Object { ($foo = $_.split(': ')[1]) }

上述技术适用于所有情况;特别是:

  • 条件:

    if ($files = Get-ChildItem *.txt) {
      "$($files.Count) text file(s) found."
    } else {
      "No text file(s) found."
    }
    
  • 单个表达式中:

    ($x = 2) * $x # -> 4
    

为了在单个管道的上下文中跨多个脚本块使用(如您的示例所示),使用通用-PipelineVariable (-pv) 参数可能会提供更优雅的解决方案,如 .

所示

I'm trying to pipe an expression, but also store it as a variable for 2 steps down the pipe

在这种情况下,您可以考虑使用 common parameter -PipelineVariable (-pv)。它的优点是变量不会像显式分配给变量那样污染管道的父范围。只要管道运行,它就会一直存在。

...| ForEach-Object -PipelineVariable foo { $_.split(': ')[1] }

一个可重现的例子会让区别更清楚:

1..3 | ForEach-Object { ($a = $_) } | ForEach-Object { $_ * 2 } | ForEach-Object { "$a * 2 = $_" }
$a  # Print the value of $a

输出:

1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
3

请注意,它在最后一行输出 $a 的值,因为该变量已从管道“泄漏”到父作用域中。当您实际上只想在管道范围内使用 $a 时,这可能是一个不需要的副作用。

现在看看当我们更改为 -PipelineVariable 时会发生什么:

1..3 | ForEach-Object -PipelineVariable a { $_ } | ForEach-Object { $_ * 2 } | ForEach-Object { "$a * 2 = $_" }
$a  # Print the value of $a

输出:

1 * 2 = 2
2 * 2 = 4
3 * 2 = 6

现在 $a 管道不输出任何内容,因为变量仅在 管道范围内定义。