PowerShell哈希表-如何选择属性



我需要从kubernetes pod中获取环境变量的值。我把我的值列在哈希表中。

我的电话$hash["service-testurl"].spec.template.spec.containers.env它返回一个表:

name                                            value
----                                            -----
ADDR                                      https://test.com
TOKEN                                     123456789
CERT_PATH                                 public-certs/test
ENVIRONMENT                               dev

我需要得到https://test.com到一个变量在我的ps1脚本,但我不知道如何得到这个值。(考虑到每个部署的url都是不同的,比如abc.com、def.com、ghj.com……所以我不能过滤test.com)

我在找类似$hash["service-testurl"].spec.template.spec.containers.env.name["ADDR"].value的东西

运行$hash["service-testurl"].spec.template.spec.containers.env.PSTypeNames返回

System.Object[]
System.Array
System.Object

补充自己的有效解决方案:

尽管$hash["service-testurl"].spec.template.spec.containers.env的显示输出看起来像,但(单个)散列表的表示,实际值为:

  • (a)andarray,如.pstypenames的诊断输出所示,

  • (b),其元素(假设)是[pscustomobject]实例,每个实例都有一个.name和一个.value属性(一种简单的方法是,显示输出的列标题是namevalue,而对于散列表,它们将是NameValue)。

先不考虑标识符ADDR是属性而不是属性/键名称,基本上不能在数组上使用基于键的索引符号(['ADDR']) -通常只适用于(单个)哈希表(或者更一般地,字典)。[1]

在您的例子中,您需要找到其.name属性值为'ADDR'的数组元素,然后允许您返回其.value属性值.

对于已经在内存中的集合,内部的.Where()方法(在您自己的解决方案中使用)是一种更有效、更灵活的替代方法Where-Objectcmdlet.

这在实践中通常无关紧要,但如果您期望或只对一个匹配感兴趣,则可以优化.Where()调用,以便在找到第一个匹配后停止过滤。

$hash["service-testurl"].spec.template.spec.containers.env.Where(
{ $_.name -eq 'ADDR' },
'First'
).value

注意.Where()总是返回一个与数组类似的集合,即使只匹配一个值——详细信息参见这个答案。因此,.value属性访问被尝试对该集合

进行访问,然而,由于PowerShell的成员访问枚举特性,它仍然按预期工作。注意如何在参数周围使用(...)现在是语法必需

而只有一个单个参数-过滤器脚本块({ ... }) -你可以摆脱不使用(...)-.Where{ $_.name -eq 'ADDR' }作为.Where({ $_.name -eq 'ADDR' })的简写-省略(...)是有问题的有两个原因:

  • 考虑到Where-Objectcmdlet也可以被称为Where(通过内置别名),这两种命令形式可能会混淆,并且考虑到Where-Object允许并且通常使用空格将命令名称与其脚本块参数分开(例如,1..3 | Where { $_ -eq 2 }),它也试图与.Where()方法一起使用空格,工作:

    # !! BROKEN, due to space before "{"
    (1..3).Where { $_ -eq 2 }
    
  • 如果稍后添加另一个参数,则需要记住使用(...)


[1]基于键的索引符号成员访问枚举一起工作,即不能在数组上工作(只有点符号可以,PowerShell也支持哈希表)可以被认为是不一致的;例如,@( @{ foo=1 } ).foo工作(点符号),但@( @{ foo=1 } )['foo']不能,由于数组包装。
然而,这种不一致被声明为设计-参见GitHub issue #17514。

我可以用类似于@iRon建议的东西来做到这一点:

$hash["service-testurl"].spec.template.spec.containers.env.where{$_.name -eq 'ADDR'}.value

谢谢!

相关内容

  • 没有找到相关文章

最新更新