如何在 powershell 中解析 json 响应
how to parse json response in powershell
通过
成功获取了 JSON 数据
$R= Invoke-WebRequest -Uri $url -Headers $headers -ContentType "application/json" -Method Get -UseBasicParsing
$x = $R.Content | Out-String | ConvertFrom-Json
现在我有一个这样的 JSON 文件 :
{
"id": 1000,
"name_with_namespace": "myProjectName1",
},
{
"id": 1001,
"name_with_namespace": "myProjectName2",
},
{
"id": 1002,
"name_with_namespace": "myProjectName3",
}
现在我需要提取 "name_with_namespace"
和 "id"
的所有出现,其中 "name_with_namespace" = "myProjectName.*"
如何一次完成?
我试过这个:
foreach ($name in $x.name_with_namespace) {
if ( $name -match ".*myProjectName.*" ) {
write-host "$name - $x.id"
}
}
但我得到了这个:
myProjectName1 1000 1001 1002
myProjectName2 1000 1001 1002
myProjectName3 1000 1001 1002
我知道问题出在 $x.id,我怎样才能得到正确的值而不是所有的值?
我的预期输出是
myProjectName1 1000
myProjectName2 1001
myProjectName3 1002
所以基本上你已经获得了父节点的json,所以我不涉及那部分。假设你已经有了父节点,那么你可以直接这样做:
$a=@"
{"ParentNode":[
{"id":1000,"name_with_namespace":"myProjectName"},
{"id":1001,"name_with_namespace":"myProjectName2"},
{"id":1002,"name_with_namespace":"myProjectName3"}
]}
"@
($a | ConvertFrom-Json).ParentNode
输出:
id name_with_namespace
-- -------------------
1000 myProjectName
1001 myProjectName2
1002 myProjectName3
您可以根据需要进行解析。那部分没有问题。确保您的 json 是您从 restAPI 接收到的结构化文件。
使用点方法,您可以进入任何级别,您也可以使用 select-object
直接 select 它们。
希望对您有所帮助。
您在定义循环时深入到一个级别。只需迭代 $x
然后检查循环内的特定 属性。
foreach ($name in $x) {
if ( $name.name_with_namespace -match ".*myProjectName.*" ) {
write-host "$($name.name_with_namespace) - $($name.id)"
}
}
编辑: 附带说明一下,您可以将 -match
简化为 "myProjectName"
,它同样有效,而且可能更快。
ConvertFrom-Json
有一些 odd behavior with pipelines。问题是 ConvertFrom-Json
将 JSON 数组包装在一个数组中,然后 将整个数组 作为一个项目传递到管道中。在大多数情况下这很好,但是如果最外层是一个 JSON 数组,那么整个数组将作为单个对象传递到管道中。
比较:
PS> ConvertFrom-Json '[1, 2, 3]' | ForEach-Object {": $_"}
: 1 2 3
PS> (ConvertFrom-Json '[1, 2, 3]') | ForEach-Object {": $_"}
: 1
: 2
: 3
PS> $x = ConvertFrom-Json '[1, 2, 3]'
PS> $x | ForEach-Object {": $_"}
: 1
: 2
: 3
PS> ,$x | ForEach-Object {": $_"}
: 1 2 3
请注意最后一个示例,我们可以使用一元逗号运算符重现该问题。
PowerShell Core 6 here 已报告此问题。
试试这个代码:
$j = @'
[
{
"id": 1000,
"name_with_namespace": "myProjectName1"
},
{
"id": 1001,
"name_with_namespace": "myProjectName2"
},
{
"id": 1002,
"name_with_namespace": "myProjectName3"
}
]
'@
($j | Out-String | ConvertFrom-Json) |
Where-Object name_with_namespace -match ".*myProjectName.*" |
ForEach-Object {
"$($_.name_with_namespace) $($_.id)"
}
通过
成功获取了 JSON 数据$R= Invoke-WebRequest -Uri $url -Headers $headers -ContentType "application/json" -Method Get -UseBasicParsing
$x = $R.Content | Out-String | ConvertFrom-Json
现在我有一个这样的 JSON 文件 :
{
"id": 1000,
"name_with_namespace": "myProjectName1",
},
{
"id": 1001,
"name_with_namespace": "myProjectName2",
},
{
"id": 1002,
"name_with_namespace": "myProjectName3",
}
现在我需要提取 "name_with_namespace"
和 "id"
的所有出现,其中 "name_with_namespace" = "myProjectName.*"
如何一次完成?
我试过这个:
foreach ($name in $x.name_with_namespace) {
if ( $name -match ".*myProjectName.*" ) {
write-host "$name - $x.id"
}
}
但我得到了这个:
myProjectName1 1000 1001 1002
myProjectName2 1000 1001 1002
myProjectName3 1000 1001 1002
我知道问题出在 $x.id,我怎样才能得到正确的值而不是所有的值?
我的预期输出是
myProjectName1 1000
myProjectName2 1001
myProjectName3 1002
所以基本上你已经获得了父节点的json,所以我不涉及那部分。假设你已经有了父节点,那么你可以直接这样做:
$a=@"
{"ParentNode":[
{"id":1000,"name_with_namespace":"myProjectName"},
{"id":1001,"name_with_namespace":"myProjectName2"},
{"id":1002,"name_with_namespace":"myProjectName3"}
]}
"@
($a | ConvertFrom-Json).ParentNode
输出:
id name_with_namespace
-- -------------------
1000 myProjectName
1001 myProjectName2
1002 myProjectName3
您可以根据需要进行解析。那部分没有问题。确保您的 json 是您从 restAPI 接收到的结构化文件。
使用点方法,您可以进入任何级别,您也可以使用 select-object
直接 select 它们。
希望对您有所帮助。
您在定义循环时深入到一个级别。只需迭代 $x
然后检查循环内的特定 属性。
foreach ($name in $x) {
if ( $name.name_with_namespace -match ".*myProjectName.*" ) {
write-host "$($name.name_with_namespace) - $($name.id)"
}
}
编辑: 附带说明一下,您可以将 -match
简化为 "myProjectName"
,它同样有效,而且可能更快。
ConvertFrom-Json
有一些 odd behavior with pipelines。问题是 ConvertFrom-Json
将 JSON 数组包装在一个数组中,然后 将整个数组 作为一个项目传递到管道中。在大多数情况下这很好,但是如果最外层是一个 JSON 数组,那么整个数组将作为单个对象传递到管道中。
比较:
PS> ConvertFrom-Json '[1, 2, 3]' | ForEach-Object {": $_"}
: 1 2 3
PS> (ConvertFrom-Json '[1, 2, 3]') | ForEach-Object {": $_"}
: 1
: 2
: 3
PS> $x = ConvertFrom-Json '[1, 2, 3]'
PS> $x | ForEach-Object {": $_"}
: 1
: 2
: 3
PS> ,$x | ForEach-Object {": $_"}
: 1 2 3
请注意最后一个示例,我们可以使用一元逗号运算符重现该问题。
PowerShell Core 6 here 已报告此问题。
试试这个代码:
$j = @'
[
{
"id": 1000,
"name_with_namespace": "myProjectName1"
},
{
"id": 1001,
"name_with_namespace": "myProjectName2"
},
{
"id": 1002,
"name_with_namespace": "myProjectName3"
}
]
'@
($j | Out-String | ConvertFrom-Json) |
Where-Object name_with_namespace -match ".*myProjectName.*" |
ForEach-Object {
"$($_.name_with_namespace) $($_.id)"
}