本文介绍了带有格式运算符的 Powershell 颜色格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在脚本中使用格式运算符,示例如下:

I'm using a format operator inside a script with a following example:

$current = 1
$total   = 1250
$userCN  = "contoso.com/CONTOSO/Users/Adam Smith"

"{0, -35}: {1}" -f "SUCCESS: Updated user $current/$total", $userCN

这 expectedly 显示以下输出:

This excpectedly shows the following output:

成功:更新用户 1/1250:contoso.com/CONTOSO/Users/Adam Smith

格式运算符用于将目标输出文本保持在原位,当前/总运行数字在 1-99999 之间变化.如果没有格式运算符,我可以像这样突出显示成功行:

The format operator is there to keep the targeted output text in place with current / total running numbers varying between 1-99999. Without the format operator I could highlight the success line like this:

Write-Host -BackgroundColor Black -ForegroundColor Green "SUCCESS: Updated user $current/$total: $userCN"

但问题是如何将高亮颜色与格式运算符结合使用?只有 -f 参数,它不允许颜色参数,因为它与 Write-Host 一开始就不是一回事.

But the question is how could I use the highlight-colors combined with the format operator? There's only the -f parameter and it doesn't allow the color parameters because, well, it's not the same thing as Write-Host in the first place.

推荐答案

与其他 shell 不同,PowerShell 允许您通过 将命令和表达式作为 命令参数 传递>将它们括在括号中,即通过使用(...)分组运算符.

Unlike other shells, PowerShell allows you to pass commands and expressions as command arguments simply by enclosing them in parentheses, i.e by using (...), the grouping operator.

在调用 PowerShell 命令(cmdlet、脚本、函数)时,输出按原样作为参数传递,作为其原始输出类型.

When calling PowerShell commands (cmdlets, scripts, functions), the output is passed as-is as an argument, as its original output type.

因此,Theo 来自评论的解决方案是正确的:

Therefore, Theo's solution from a comment is correct:

Write-Host -BackgroundColor Black -ForegroundColor Green `
           ("{0, -35}: {1}" -f "SUCCESS: Updated user $current/$total", $userCN)

也就是说,(...) 中的 -f 表达式被执行,它的输出 - 在这种情况下是一个单独的字符串 - 作为位置参数传递给Write-Host(隐式绑定到 -Object 参数).

That is, the -f expression inside (...) is executed and its output - a single string in this case - is passed as a positional argument to Write-Host (implicitly binds to the -Object parameter).

请注意,不需要$(...)子表达式运算符,在这种情况下:强>

Note that you do not need, $(...), the subexpression operator, in this case:

(...) 足以包含表达式或命令.

(...) is sufficient to enclose an expression or command.

事实上,在某些情况下,$(...) 可能会不经意地修改你的论点,因为它解开单元素数组:

In fact, in certain cases $(...) can inadvertently modify your argument, because it unwraps single-element arrays:

# Pass a single-element array to a script block (which acts like a function).
# (...) preserves the array as-is.
PS> & { param($array) $array.GetType().Name } -array ([array] 1)
Object[]  # OK - single-element array was passed as-is

# $(...) unwraps it.
PS> & { param($array) $array.GetType().Name } -array $([array] 1)
Int32  # !! Single-element array was unwrapped.

$(...) 的主要用途是:

The primary use of $(...) is:

  • expanding the output from expressions or commands inside expandable strings (string interpolation)

发送复合语句输出,例如foreach (...) { ... }>if (...) { ... }multiple 语句直接通过管道,在收集输出之前 (其中 (...) 也是如此);但是,您也可以将此类语句包装起来 &{ ... }(或 . { ... } 以便直接在调用者的范围内执行而不是在子范围内执行)以获得通常的 管道中的行为(逐一传递输出).

To send the output from compound statements such as foreach (...) { ... } and if (...) { ... } or multiple statements directly through the pipeline, after collecting the output up front (which (...) does as well); however, you can alternatively wrap such statements & { ... } (or . { ... } in order to execute directly in the caller's scope rather than a child scope) in order to get the usual streaming behavior (one-by-one passing of output) in the pipeline.

  • 退一步:鉴于您已经可以在变量赋值中使用复合语句作为表达式 - 例如,$evenNums = foreach ($num in 1..3) { $num * 2 } - 和表达式一般被接受为管道的第一段 - 例如,'hi' |Write-Host -Fore Yellow - 令人惊讶的是,目前不适用于复合语句;此 GitHub 问题询问是否可以解除此限制.
  • Taking a step back: Given that you already can use compound statements as expressions in variable assignments - e.g., $evenNums = foreach ($num in 1..3) { $num * 2 } - and expressions generally are accepted as the first segment of a pipeline - e.g., 'hi' | Write-Host -Fore Yellow - it is surprising that that currently doesn't work with compound statements; this GitHub issue asks if this limitation can be lifted.

在将参数传递给命令的上下文中:

In the context of passing arguments to commands:

  • 使用 $(...)子表达式运算符 仅当你想通过多个命令或(一个或多个)复合语句的输出作为参数和/或,如果输出恰好是一个single 对象,您希望该对象按原样使用,或者,如果它恰好是一个单元素数组(可枚举),您希望它展开(通过元素本身,而不是数组.

  • Use $(...), the subexpression operator only if you want to pass the output from multiple commands or (one or more) compound statements as an argument and/or, if the output happens to be a single object, you want that object to be used as-is or, if it happens to be a single-element array (enumerable), you want it to be unwrapped (pass the element itself, not the array.

  • 当然,如果您正在构造一个 string 参数,$(...) 在该字符串中 很有用,因为字符串插值 - 例如,Write-Host1 + 1 = $(1 + 1)"
  • Of course, if you're constructing a string argument, $(...) can be useful inside that string, for string interpolation - e.g., Write-Host "1 + 1 = $(1 + 1)"

使用 @(...)数组子表达式运算符 仅当你想要将多个命令的输出作为参数和/或你想要确保输出变成一个数组em>;也就是说,输出作为(常规 PowerShell)数组返回,类型为 [object[]],即使它恰好包含 一个 对象.从某种意义上说,它是 $(...) 在单对象输出情况下的行为的:它确保单对象输出也变成一个数组.

Use @(...), the array subexpression operator only if you want to pass the output from multiple commands as an argument and/or you want to ensure that the output becomes a array; that is, the output is returned as a (regular PowerShell) array, of type [object[]], even if it happens to comprise just one object. In a manner of speaking it is the inverse of $(...)'s behavior in the single-object output case: it ensures that single-object output too becomes an array.

这篇关于带有格式运算符的 Powershell 颜色格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 00:41