遍历JSON文件PowerShell

我试图在PowerShell中遍历以下JSON文件。

如果没有专门命名顶部标签(例如17443和17444),由于我事先不知道它们的名称,就无法找到遍历数据的方法。

我想为所有记录输出标签3、4和5(标题,名字,姓氏)。

我该怎么做?

{

"17443":{

"sid":"17443",

"nid":"7728",

"submitted":"1436175407",

"data":{

"3":{

"value":[

"Mr"

]

},

"4":{

"value":[

"Jack"

]

},

"5":{

"value":[

"Cawles"

]

}

} },

"17444":{

"sid":"17444",

"nid":"7728",

"submitted":"1436891400",

"data":{

"3":{

"value":[

"Miss"

]

},

"4":{

"value":[

"Charlotte"

]

},

"5":{

"value":[

"Tann"

]

}

}

},

"17445":{

"sid":"17445",

"nid":"7728",

"submitted":"1437142325",

"data":{

"3":{

"value":[

"Mr"

]

},

"4":{

"value":[

"John"

]

},

"5":{

"value":[

"Brokland"

]

}

}

}

}

我可以使用下面的代码访问数据,但我想避免放入17443、17444等。

$data = ConvertFrom-Json $json

foreach ($i in $data.17443)

{

foreach ($t in $i.data.3)

{

Write-Host $t.value

}

foreach ($t in $i.data.4)

{

Write-Host $t.value

}

foreach ($t in $i.data.5)

{

Write-Host $t.value

}

}

回答:

PowerShell 3.0+

在PowerShell

3.0及更高版本中(请参阅:确定已安装的PowerShell版本),可以使用ConvertFrom-

Jsoncmdlet将JSON字符串转换为PowerShell数据结构。

这既方便又不幸-方便,因为它很容易使用JSON,不幸的是,由于ConvertFrom-

Json给了您PSCustomObjects,它们很难作为键值对进行迭代。

当您知道键之后,就没有什么要迭代的了–您只需直接访问它们,例如$result.thisKey.then.thatKey.array[1],就可以完成。

但是在此特定的JSON中,键似乎是动态的/不为人所知,例如"17443""17444"。这意味着我们需要可以将其PSCustomObject变成foreach可以理解的键值列表的东西。

# helper to turn PSCustomObject into a list of key/value pairs

function Get-ObjectMembers {

[CmdletBinding()]

Param(

[Parameter(Mandatory=$True, ValueFromPipeline=$True)]

[PSCustomObject]$obj

)

$obj | Get-Member -MemberType NoteProperty | ForEach-Object {

$key = $_.Name

[PSCustomObject]@{Key = $key; Value = $obj."$key"}

}

}

现在,我们可以遍历对象图并使用TitleFirstName和生成输出对象列表。LastName

$json = '{"17443": {"17444": {"sid": "17444","nid": "7728","submitted": "1436891400","data": {"3": {"value": ["Miss"]},"4": {"value": ["Charlotte"]},"5": {"value": ["Tann"]}}},"17445": {"sid": "17445","nid": "7728","submitted": "1437142325","data": {"3": {"value": ["Mr"]},"4": {"value": ["John"]},"5": {"value": ["Brokland"]}}},"sid": "17443","nid": "7728","submitted": "1436175407","data": {"3": {"value": ["Mr"]},"4": {"value": ["Jack"]},"5": {"value": ["Cawles"]}}}}'

$json | ConvertFrom-Json | Get-ObjectMembers | foreach {

$_.Value | Get-ObjectMembers | where Key -match "^\d+$" | foreach {

[PSCustomObject]@{

Title = $_.value.data."3".value | select -First 1

FirstName = $_.Value.data."4".value | select -First 1

LastName = $_.Value.data."5".value | select -First 1

}

}

}

输出量

标题名姓                 

----- --------- --------

夏洛特·坦恩小姐

约翰·布罗克兰先生


PowerShell 2.0 /替代方法

另一种适用于PowerShell 2.0的替代方法(不支持上述某些构造)将涉及使用.NET

JavaScriptSerializer类来处理JSON:

Add-Type -AssemblyName System.Web.Extensions

$JS = New-Object System.Web.Script.Serialization.JavaScriptSerializer

现在我们可以做一个非常类似的操作-

比上面的操作还要简单一些,因为JavaScriptSerializer为您提供了常规的Dictionary,这些字典很容易通过以下GetEnumerator()方法作为键值对进行迭代:

$json = '{"17443": {"17444": {"sid": "17444","nid": "7728","submitted": "1436891400","data": {"3": {"value": ["Miss"]},"4": {"value": ["Charlotte"]},"5": {"value": ["Tann"]}}},"17445": {"sid": "17445","nid": "7728","submitted": "1437142325","data": {"3": {"value": ["Mr"]},"4": {"value": ["John"]},"5": {"value": ["Brokland"]}}},"sid": "17443","nid": "7728","submitted": "1436175407","data": {"3": {"value": ["Mr"]},"4": {"value": ["Jack"]},"5": {"value": ["Cawles"]}}}}'

$data = $JS.DeserializeObject($json)

$data.GetEnumerator() | foreach {

$_.Value.GetEnumerator() | where { $_.Key -match "^\d+$" } | foreach {

New-Object PSObject -Property @{

Title = $_.Value.data."3".value | select -First 1

FirstName = $_.Value.data."4".value | select -First 1

LastName = $_.Value.data."5".value | select -First 1

}

}

}

输出是相同的:

标题名姓                 

----- --------- --------

夏洛特·坦恩小姐

约翰·布罗克兰先生

如果JSON大于4

MB,则相应地设置JavaScriptSerializer.MaxJsonLength属性。


从文件读取JSON时

如果您从文件中读取,请使用Get-Content -Raw -Encoding UTF-8

  • -Raw因为否则Get-Content返回一个单独行的数组,JavaScriptSerializer.DeserializeObject将无法处理。最新的Powershell版本似乎对.NET函数参数进行了改进的类型转换,因此它可能不会在您的系统上出错,但是如果这样做(或者为了安全起见),请使用-Raw
  • -Encoding因为在阅读时指定文本文件的编码是明智的做法,并且这UTF-8是JSON文件最可能的值。


笔记

  • 构建包含包含具有不可预测键的项的JSON时,请优先选择像{items: [{key: 'A', value: 0}, {key: 'B', value: 1}]}over 这样的数组结构{'A': 0, 'B': 1}。后者似乎更直观,但既难以生成又难以使用。
  • ConvertFrom-Json()为您提供一个PSCustomObject可反映JSON字符串中数据的PowerShell自定义对象()。
  • 您可以通过以下方式循环自定义对象的属性: Get-Member -type NoteProperty
  • 您可以使用$object."$propName"语法动态地访问对象的属性$object."$(some PS expression)"
  • 您可以创建自己的自定义对象,并使用New-Object PSObject -Property @{...},或[PSCustomObject]@{ .. } `

以上是 遍历JSON文件PowerShell 的全部内容, 来源链接: utcz.com/qa/423936.html

回到顶部