Powershell从非常奇怪的JSON文件中提取数据



我有一个非常奇怪的json文件,我试图通过powershell从它提取数据。

问题是这个文件的创建者以一种我从未见过的方式使用json:

(城市不在数组中,大陆不在数组中等)

缩短JSON文件:

{
"zscloud.net": {
"continent : EMEA": {
"city : Abu Dhabi I": [
{
"range": "147.161.174.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "24.453884",
"longitude": "54.3773438"
}
],
"city : Amsterdam II": [
{
"range": "185.46.212.0/23",
"vpn": "amsterdam2-vpn.zscloud.net",
"gre": "185.46.212.36",
"hostname": "ams2.sme.zscloud.net",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.228.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "165.225.240.0/23",
"vpn": "ams2-2-vpn.zscloud.net",
"gre": "165.225.240.42",
"hostname": "ams2-2.sme.zscloud.net",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.172.0/23",
"vpn": "",
"gre": "165.225.240.42",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.230.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.232.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.234.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.224.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.226.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
}
]
}
}

}

我正在尝试获取城市名称+嵌套的主机名。

我的选择:

  1. 我可以使用Convertfrom-JSON,然后以某种方式迭代几个未知的键和属性。

  2. 或者我可以使用select-string,基本上只grep匹配的正则表达式。然后将它们放入数组等

以前,我使用选择字符串而不是美化JSON,因为它更容易。

今天,我发现不仅需要Hostname,还需要Hostname + City name。知道如何从json中提取它们吗?

我在PS5上。

很多谢谢,Aster

我可以使用ConvertFrom-JSON然后以某种方式迭代几个未知的键和属性.

让我告诉你怎么做!

PowerShell允许您通过psobject隐藏成员集以编程方式发现任何对象的属性:

PS ~> $someObject = [pscustomobject]@{ A = 123; B = "a string value" }
PS ~> $someObject.psobject.Properties

MemberType      : NoteProperty
IsSettable      : True
IsGettable      : True
Value           : 123
TypeNameOfValue : System.Int32
Name            : A
IsInstance      : True
MemberType      : NoteProperty
IsSettable      : True
IsGettable      : True
Value           : a string value
TypeNameOfValue : System.String
Name            : B
IsInstance      : True

应用到JSON输入,我们可以这样做:

# The following assumes you've loaded the JSON into a string like below
$json = @'
{
"zscloud.net": {
"continent : EMEA": {
"city : Abu Dhabi I": [
{
"range": "147.161.174.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "24.453884",
"longitude": "54.3773438"
}
],
"city : Amsterdam II": [
{
"range": "185.46.212.0/23",
"vpn": "amsterdam2-vpn.zscloud.net",
"gre": "185.46.212.36",
"hostname": "ams2.sme.zscloud.net",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.228.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "165.225.240.0/23",
"vpn": "ams2-2-vpn.zscloud.net",
"gre": "165.225.240.42",
"hostname": "ams2-2.sme.zscloud.net",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.172.0/23",
"vpn": "",
"gre": "165.225.240.42",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.230.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.232.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.234.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.224.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
},
{
"range": "147.161.226.0/23",
"vpn": "",
"gre": "",
"hostname": "",
"latitude": "52",
"longitude": "5"
}
]
}
}
}
'@

现在对于实际代码:

# Convert json to an object
$data = $json |ConvertFrom-Json
# Iterate over each property (cloud provider?) on the root object
foreach($provider in $data.psobject.Properties){
# save the provider name for later
$providerName = $provider.Name
# Iterate over each property (geographic region?) on the provider object
foreach($region in $provider.Value.psobject.Properties){
# save the region name for later, remove the `continent : ` prefix
$regionName = $region.Name -replace '^.*?:s*'
# Iterate over each property (datacenter location?) on the region object
foreach($location in $region.Value.psobject.Properties){
# save the location name for later, remove the `city : ` prefix
$locationName = $location.Name -replace '^.*?:s*'
# Extract the network information, attach the parent details
$location.Value |Select-Object *,@{Name='provider';Expression={$providerName}},@{Name='region';Expression={$regionName}},@{Name='location';Expression={$locationName}},
}
}
}

对于,您将得到这样的输出,更容易使用:

range     : 147.161.174.0/23
vpn       :
gre       :
hostname  :
latitude  : 24.453884
longitude : 54.3773438
provider  : zscloud.net
region    : EMEA
location  : Abu Dhabi I
range     : 185.46.212.0/23
vpn       : amsterdam2-vpn.zscloud.net
gre       : 185.46.212.36
hostname  : ams2.sme.zscloud.net
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II
range     : 147.161.228.0/23
vpn       :
gre       :
hostname  :
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II
range     : 165.225.240.0/23
vpn       : ams2-2-vpn.zscloud.net
gre       : 165.225.240.42
hostname  : ams2-2.sme.zscloud.net
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II
range     : 147.161.172.0/23
vpn       :
gre       : 165.225.240.42
hostname  :
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II
range     : 147.161.230.0/23
vpn       :
gre       :
hostname  :
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II
range     : 147.161.232.0/23
vpn       :
gre       :
hostname  :
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II
range     : 147.161.234.0/23
vpn       :
gre       :
hostname  :
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II
range     : 147.161.224.0/23
vpn       :
gre       :
hostname  :
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II
range     : 147.161.226.0/23
vpn       :
gre       :
hostname  :
latitude  : 52
longitude : 5
provider  : zscloud.net
region    : EMEA
location  : Amsterdam II

最新更新