如何在PowerShell中遍历JSON数据结构?
How to traverse through JSON data structure in PowerShell?
我是 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 hashtable/dictionary 并调用一个函数。
请检查下面我的回答:
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.$_)
}
在进入正题之前,让我们回顾一些 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
运算符是 [=41 的薄包装=],并且 String.Format()
仅 支持基于 0 的占位符 - '{0} {1}' -f 1,2
有效,但 '{} {}' -f 1,2
无效。
另一种选择是将表达式包装在双引号字符串文字中的 $()
子表达式运算符中:
$mymeters = [ordered]@{}
"Here is item '500 HR': $($mymeters['500 HR'])"
请注意,PowerShell 中的字典支持使用 []
的键控索引访问 - 就像 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()
:
$dictionary = [ordered]@{ A = 1; B = 2; C =3 }
foreach($keyValuePair in $dictionary.GetEnumerator()){
"Dictionary Entry: {0} = {1}" -f $keyValuePair.Key,$keyValuePair.Value
}
我是 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 hashtable/dictionary 并调用一个函数。
请检查下面我的回答:
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.$_)
}
在进入正题之前,让我们回顾一些 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
运算符是 [=41 的薄包装=],并且 String.Format()
仅 支持基于 0 的占位符 - '{0} {1}' -f 1,2
有效,但 '{} {}' -f 1,2
无效。
另一种选择是将表达式包装在双引号字符串文字中的 $()
子表达式运算符中:
$mymeters = [ordered]@{}
"Here is item '500 HR': $($mymeters['500 HR'])"
请注意,PowerShell 中的字典支持使用 []
的键控索引访问 - 就像 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()
:
$dictionary = [ordered]@{ A = 1; B = 2; C =3 }
foreach($keyValuePair in $dictionary.GetEnumerator()){
"Dictionary Entry: {0} = {1}" -f $keyValuePair.Key,$keyValuePair.Value
}