通过符号名称(键)从脚本访问多个输出

Access multiple outputs from a script by symbolic names (keys)

我是 powershell 脚本的初学者,我希望能够区分脚本的输出。让我们以这个脚本测试为例。ps1:

param([System.String] $w)
$x=$w+" is correct"
$y=$w+ " is false"
$x
$y

要执行它并检索值 $x 和 $y,我正在这样做:

$a=.\test1.ps1 -w test
$a[0] #this is x
$a[1] # this is y

有没有一种方法可以使用类似于 $a.x 的东西来检索 $x 值?

谢谢。

要执行您想要的操作,您需要一个包含 key/value 对或命名属性的对象。例如,您可以创建一个名为 a 的对象,其属性为 xy:

$x = "one"
$y = "two"
$a = [pscustomobject]@{"x"=$x;"y"=$y}

测试上述案例:

$a

x   y
-   -
one two

$a.x
one
$a.y
two

我喜欢 link PSCustomObjects 关于创建和使用自定义对象的解释。

使用函数进行测试:

function test {

param([string] $w)

$x = $w + "x"
$y = $w + "y"

[pscustomobject]@{"x"=$x; "y"=$y}
}

$a = test "my property "
$a

x             y
-             -
my property x my property y


$a.x
my property x
$a.y
my property y

展示了一种提供基于键的值访问的方法,[pscustomobject].

一般来说,您正在寻找字典散列table (hashtable):键值对的集合,允许通过关联键高效查找值。

事实上,链接答案中的 [pscustomobject] 技术在语法上基于 PowerShell 的 hashtable literal 语法,@{ <key> = <value>; ... }[1].

为简洁起见,使用脚本块 ({ ... }) 而不是 script/function 的示例:

$output = & { 
  # Output a hashtable
  @{ x = 'one'; y = 'two' } 
}

# Access the entries by key:

# Index syntax:
$output['x'] # -> 'one'
$output['y'] # -> 'two'

# Dot notation, as with objects, works too.
# While this is convenient, it is much slower with variable-based keys;
# e.g., $output.$keyName - this typically won't matter, but may in loops
# with a high number of iterations.
$output.x # -> 'one'
$output.y # -> 'two'

如果枚举条目的顺序很重要,请使用 ordered hashtable (PSv3+):[ordered] @{ <key> = <value>; ... }.
使用有序散列 table 只会带来可忽略不计的性能损失,因此我建议习惯使用 [ordered],因为它可以提供更好的输出和调试体验,以查看相同的条目它们的定义顺序。


[pscustomobject] 和散列之间进行选择table:

  • 如果您将输出设想为具有存储在属性中的值的单个对象,请使用 [pscustomobject],但请注意,构建对象比构建哈希要慢table.

  • 如果输出只是键值对的集合,使用(n个有序的)散列table.

如果性能很重要(在多次迭代的循环中):

  • 使用(有序)hashtables.

  • 对非文字键(例如,$key = 'one'; $ht[$key])使用索引访问,这比非文字点符号(例如, , $key = 'one'; $ht.$key)


[1] 但是请注意,[pscustomobject] @{ ... } 语法糖 ,因为自定义对象 直接 构造 - 没有创建中间散列table;此外,hashtable 键定义的属性在 definition order 中定义,而 hashtable 保证其条目没有特定的顺序,除非您使用 [ordered] @{ ... }.