微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在PowerShell中遍历JSON数据结构?

如何解决如何在PowerShell中遍历JSON数据结构?

我是 PowerShell 的新手,正在从 Python 背景学习它。

我正在从另一个工具中提取数据,该工具通过 REST 调用检索数据。

METERS 变量以这种格式存储在源中。

{
    "500 HR": 500,"1000 HR": 1000,"2000 HR": 2000
}

PowerShell 代码

#REST call to source
$meter=@{}
Foreach ($item in $origresult.Items)  {
$result = (Invoke-RestMethod -Uri $url  -Headers $headers -Method GET -ContentType application/json -ErrorVariable RespErr)
$meter.Add($item.Name,$result.Value)
}
Write-Host ($meter | Out-String) -ForegroundColor Red

这是输出

Name                           Value
----                           -----
LastUploaded                   2020-12-29T06:38:02
IsEnabled                      1       
METERS                         {...
ORGID                          WHS

如何检索 METERS 并遍历字典?到目前为止我试过这个。 Python 以其简单的数据结构宠坏了我,除非有更简单的方法来做到这一点,否则 PowerShell 就不那么简单了。

$mymeters = $meter.METERS | ConvertFrom-Json
Write-Host ($mymeters | Out-String) -ForegroundColor Yellow

输出

500 HR   : 500
1000 HR  : 1000
2000 HR  : 2000

这是我迄今为止尝试过的东西-

$mymeters = [ordered]@{}
" Here is the item $mymeters.Get_Item(500 HR)" #my silly attempt!
# Looping is a no go either - it says specialized ordered dictionary
foreach ($ind in $mymeters) {
" --> $ind"
}

输出

 Here is the item System.Collections.Specialized.OrderedDictionary.Get_Item(500 HR)
 --> System.Collections.Specialized.OrderedDictionary

我可能遗漏了一些真正的基本知识,但我无法自己弄清楚!任何帮助都非常感谢。我想要的只是遍历 METERS 哈希表/字典并调用一个函数

解决方法

在深入了解它之前,让我们回顾一些 PowerShell 语法基础知识,看看我们是否可以重用您的一些 Pythonic 直觉:)

会员访问

就像在 Python 中一样,您可以使用 . 成员访问运算符通过 name 引用对象的属性 - 对于非连续名称,请使用引号:

$mymeters = $meter.METERS | ConvertFrom-Json
$mymeters.'500 HR'  # evaluates to `500`

字符串表达式

PowerShell 中的字符串文字有两种不同的风格:

  • 单引号字符串 ('Hello World!')
    • 这些是逐字字符串文字,唯一支持的转义序列是''(文字单引号)
  • 双引号字符串 ("Hello World!")
    • 这些是可扩展字符串文字 - 除非显式转义,否则会自动插入 $variable 标记和 $() 子表达式 - ` 是转义字符,并且很常见您在大多数类 C 语言(`n`t`r 等)中期望的序列都被本地识别。

任意表达式(如 $dictionary.get_Item('some key')不会按原样计算。

为了解决这个问题,我们可以使用 -f 字符串格式运算符:

$mymeters = [ordered]@{}
"Here is item '500 HR': {0}" -f $mymeters['500 HR']
如果您习惯了 Python3 的 -f 字符串,

f 应该会感觉很熟悉,但需要注意 - PowerShell 的 -f 运算符是 String.Format() 的薄包装器,而 {{1 }} 支持基于 0 的占位符 - String.Format() 有效但 '{0} {1}' -f 1,2 无效。

另一种选择是将表达式包装在双引号字符串文字内的 '{} {}' -f 1,2 子表达式运算符中:

$()

请注意,PowerShell 中的字典支持使用 $mymeters = [ordered]@{} "Here is item '500 HR': $($mymeters['500 HR'])" 键控索引访问 - 就像 Python :)


与 Python 不同,PowerShell(以及一般的 .NET)也具有强大的内省功能。

动态发现和迭代任何对象的属性就像引用一个名为 [] 的特殊成员一样简单:

psobject

或者在您的情况下:

foreach($propertyMetadataEntry in $someObject.psobject.Properties){
    "Property: {0,-20} = {1}" -f $propertyMetadataEntry.Name,$propertyMetadataEntry.Value
}

这适用于任何标量对象(如$mymeters = $meter.METERS | ConvertFrom-Json foreach($meterReading in $mymeters.psobject.Properties){ "Meter: {0,-20} = {1}" -f $meterReading.Name,$meterReading.Value # do whatever else you please with $meterReading here :) } ConvertFrom-Json返回的对象)。

要遍历字典中的条目,您需要显式调用 Invoke-RestMethod:

.GetEnumerator()
,

请在下面查看我的回答:

1.) 我在 powershell 5.x 上测试了这些东西。较新或较旧版本的 powershell(尤其是较旧版本)的工作方式可能略有不同

2.) Invoke-Restmethod 会自动将 json 响应转换为 powershell 对象,因此无需进一步处理。把所有的分配都去掉到一个哈希表中。

$responseJson = '{
    "500 HR": 500,"1000 HR": 1000,"2000 HR": 2000
}'

$response = $responseJson | ConvertFrom-Json

$nodes = (Get-Member -inputobject $response  -MemberType NoteProperty).Name

$nodes | ForEach-Object {
    echo ("Element: $_ Result: " +$response.$_)
    
}

echo "Another one"

#alternative
foreach ($node in $nodes) {
    echo ("Element: $node Result: " +$response.$node)
}

3.) 我认为响应的格式不正确,因此如果您可以控制 restservice,我建议您这样做:

$responseJson = '{
    "hr": [
     500,1000,2000
    ]
}'

$response = $responseJson | ConvertFrom-Json

$response.hr | ForEach-Object {
    echo ("Element: $_ Result: " +$response.$_)
    
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。