我有一个json文件(test.json),看起来像这样:
{
"root":
{
"key":"value"
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用类似这样的东西将它加载到powershell中:
PS > $data = [System.String]::Join("", [System.IO.File]::ReadAllLines("test.json")) | ConvertFrom-Json
root
----
@{key=value}
Run Code Online (Sandbox Code Playgroud)
我希望能够枚举由json文件定义的'hashtable'之类的对象的键. 所以,理想情况下,我希望能够做到这样的事情:
$data.root.Keys
Run Code Online (Sandbox Code Playgroud)
并得到["关键"].我可以使用PowerShell中的内置哈希表来做到这一点,但是使用从json加载的哈希表来做这件事并不那么明显.
在对此进行故障排除时,我注意到ConvertFrom-json返回的字段与Powershell的哈希表的字段类型不同.例如,在内置哈希表上调用.GetType()会显示它的类型为'Hashtable':
PS > $h = @{"a"=1;"b"=2;"c"=3}
PS > $h.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Hashtable System.Object
Run Code Online (Sandbox Code Playgroud)
为我的json对象做同样的事情会产生PSCustomObject:
PS > $data.root.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
Run Code Online (Sandbox Code Playgroud)
有没有办法将此对象转换或转换为典型的PowerShell Hashtable?
Dun*_*can 12
该ConvertFrom-Jsoncmdlet将让你自定义对象,所以你必须使用点符号来访问它们,而不是作为一个下标.通常你会知道你在JSON中期望的字段,所以这实际上比获取哈希表更有用.我建议您使用它,而不是通过转换回哈希表来对抗系统.
您可以使用select通配符属性名来获取属性:
PS D:\> $data = @"
{
"root":
{
"key":"value", "key2":"value2", "another":42
}
}
"@ | ConvertFrom-Json
PS D:\> $data.root | select * | ft -AutoSize
key key2 another
--- ---- -------
value value2 42
PS D:\> $data.root | select k* | ft -AutoSize
key key2
--- ----
value value2
Run Code Online (Sandbox Code Playgroud)
而Get-Member如果要提取,你可以遍历属性名称的列表:
PS D:\> ($data.root | Get-Member -MemberType NoteProperty).Name
another
key
key2
Run Code Online (Sandbox Code Playgroud)
将它放入循环可以得到如下代码:
PS D:\> foreach ($k in ($data.root | Get-Member k* -MemberType NoteProperty).Name) {
Write-Output "$k = $($data.root.$k)"
}
key = value
key2 = value2
Run Code Online (Sandbox Code Playgroud)
小智 9
这是一个快速函数,用于将PSObject转换回哈希表(支持嵌套对象;旨在与DSC ConfigurationData一起使用,但可以在任何需要的地方使用).
function ConvertPSObjectToHashtable
{
param (
[Parameter(ValueFromPipeline)]
$InputObject
)
process
{
if ($null -eq $InputObject) { return $null }
if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string])
{
$collection = @(
foreach ($object in $InputObject) { ConvertPSObjectToHashtable $object }
)
Write-Output -NoEnumerate $collection
}
elseif ($InputObject -is [psobject])
{
$hash = @{}
foreach ($property in $InputObject.PSObject.Properties)
{
$hash[$property.Name] = ConvertPSObjectToHashtable $property.Value
}
$hash
}
else
{
$InputObject
}
}
}
Run Code Online (Sandbox Code Playgroud)
该示例针对相对较浅的源对象(不是属性中的嵌套对象)。
这是一个深入源对象 2 层的版本,并且应该适用于您的数据:
$data = @{}
foreach ($propL1 in $x.psobject.properties.name)
{
$data[$propL1] = @{}
foreach ($propL2 in $x.$propL1.psobject.properties.name)
{
$data[$PropL1][$PropL2] = $x.$propL1.$propL2
}
}
$data.root.keys
key
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15398 次 |
| 最近记录: |