用于提取 json 数据的 PowerShell 2.0 脚本
PowerShell 2.0 script to extract json data
更新 - Powershell 5.1 的解决方案非常简单。我单独发布了一个答案
我正在尝试我的第一个 Powershell 脚本(Windows 7 中的 2.0 版)。我正在从文件中读取以下 json 文本(该部分有效)。我想获得“public_url”的值。我在下面的脚本中遇到的错误是“
Select-Object : Property "tunnels" cannot be found
我是第一次使用 Powershell,我不太了解如何导航对象。提前致谢,
我的json文件内容:
{
"tunnels":[
{
"name":"command_line",
"uri":"/api/tunnels/command_line",
"public_url":"tcp://8.tcp.ngrok.io:12716",
"proto":"tcp",
"config":{
"addr":"localhost:32400",
"inspect":false
},
"metrics":{
"conns":{
"count":0,
"gauge":0,
"rate1":0,
"rate5":0,
"rate15":0,
"p50":0,
"p90":0,
"p95":0,
"p99":0
},
"http":{
"count":0,
"rate1":0,
"rate5":0,
"rate15":0,
"p50":0,
"p90":0,
"p95":0,
"p99":0
}
}
}
],
"uri":"/api/tunnels"
}
我的 Powershell 脚本:
function ConvertFrom-Json20([object] $item){
add-type -assembly system.web.extensions
$ps_js=new-object system.web.script.serialization.javascriptSerializer
#The comma operator is the array construction operator in PowerShell
return ,$ps_js.DeserializeObject($item)
}
$content = get-content -path "c:\path\to\json.txt"
$json = ConvertFrom-Json20($content)
$url = $json | select -expand tunnels | select public_url
echo "url=>" $url
继续我的评论。
只需使用 JSON cmdlet 升级到最新的 WinPS,不要尝试重新发明轮子。
Windows 管理框架 5.1
https://www.microsoft.com/en-us/download/details.aspx?id=54616
Windows Management Framework 5.1 includes updates to Windows
PowerShell, Windows PowerShell Desired State Configuration (DSC),
Windows Remote Management (WinRM), Windows Management Instrumentation
(WMI). Release notes: https://go.microsoft.com/fwlink/?linkid=839460
Get-Command -Name '*json*' | Format-Table -AutoSize
# Results
<#
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet ConvertFrom-Json 3.1.0.0 Microsoft.PowerShell.Utility
Cmdlet ConvertTo-Json 3.1.0.0 Microsoft.PowerShell.Utility
#>
PowerShell 本机使用 JSON、XML,并且您可以访问所有 .Net,因此,您可以使用 JSON.
的 .Net 命名空间
只需查看有关如何使用它们的帮助文件。有完整的解释和例子。
# Get specifics for a module, cmdlet, or function
(Get-Command -Name Get-Help).Parameters
(Get-Command -Name Get-Help).Parameters.Keys
Get-help -Name Get-Help -Examples
Get-help -Name Get-Help -Full
Get-help -Name Get-Help -Online
(Get-Command -Name ConvertFrom-Json).Parameters
(Get-Command -Name ConvertFrom-Json).Parameters.Keys
Get-help -Name ConvertFrom-Json -Examples
Get-help -Name ConvertFrom-Json -Full
Get-help -Name ConvertFrom-Json -Online
(Get-Command -Name ConvertTo-Json).Parameters
(Get-Command -Name ConvertTo-Json).Parameters.Keys
Get-help -Name ConvertTo-Json -Examples
Get-help -Name ConvertTo-Json -Full
Get-help -Name ConvertTo-Json -Online
根据您的评论更新
使用上面的方法,您可以通过点引用和/或索引导航 JSON 对象。
$JsonData = '
{
"tunnels":[
{
"name":"command_line",
"uri":"/api/tunnels/command_line",
"public_url":"tcp://8.tcp.ngrok.io:12716",
"proto":"tcp",
"config":{
"addr":"localhost:32400",
"inspect":false
},
"metrics":{
"conns":{
"count":0,
"gauge":0,
"rate1":0,
"rate5":0,
"rate15":0,
"p50":0,
"p90":0,
"p95":0,
"p99":0
},
"http":{
"count":0,
"rate1":0,
"rate5":0,
"rate15":0,
"p50":0,
"p90":0,
"p95":0,
"p99":0
}
}
}
],
"uri":"/api/tunnels"
}
' |
ConvertFrom-Json
$JsonData
# Results
<#
tunnels uri
------- ---
{@{name=command_line; uri=/api/tunnels/command_line; public_url=tcp://8.tcp.ngrok.io:12716; proto=tcp; config=; metrics=}} /api/tunnels
#>
$JsonData.tunnels
# Results
<#
name : command_line
uri : /api/tunnels/command_line
public_url : tcp://8.tcp.ngrok.io:12716
proto : tcp
config : @{addr=localhost:32400; inspect=False}
metrics : @{conns=; http=}
#>
$JsonData.uri
# Results
<#
/api/tunnels
#>
$JsonData.uri.Split('/')
# Results
<#
api
tunnels
#>
$JsonData.uri.Split('/')[-1]
# Results
<#
tunnels
#>
至于你的东西……好吧,它从来都不是一个对象。只是一个字符串。
这并不像你想象的那样有效
function ConvertFrom-Json20([object] $item)
{
Add-Type -Assembly System.Web.Extensions
$ps_js = New-Object System.Web.Script.Serialization.JavascriptSerializer
return
$ps_js.DeserializeObject($item)
}
($content = Get-Content -path 'D:\Scripts\json.txt')
($json = ConvertFrom-Json20($content))
# Results
<#
Nothing is returned
#>
# So this would never work
# Results
<#
$url = $json | select -expand tunnels | select public_url
echo "url=>" $url
#>
所以,读取数据并抓取字符串
(Get-Content -path 'D:\Scripts\json.txt').Trim() |
Select-String -Pattern 'uri.*'
# Results
<#
"uri":"/api/tunnels/command_line",
"uri":"/api/tunnels"
#>
((Get-Content -path 'D:\Scripts\json.txt').Trim() |
Select-String -Pattern 'uri.*')[-1] -replace '"' -split('/')
# Results
<#
uri:
api
tunnels
#>
(((Get-Content -path 'D:\Scripts\json.txt').Trim() |
Select-String -Pattern 'uri.*')[-1] -replace '"' -split('/'))[-1]
# Results
<#
tunnels
#>
要从那个 JSON 文件中获取一个对象,在 PSv2 中,你会说做这样的事情。
[void][System.Reflection.Assembly]::LoadWithPartialName('System.Web.Extensions')
$JsonData = Get-Content -Path 'D:\Scripts\Json.txt'
$Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer
($JsonObject = $Serializer.DeserializeObject($JsonData))
# Results
<#
Key Value
--- -----
tunnels {System.Collections.Generic.Dictionary`2[System.String,System.Object]}
uri /api/tunnels
#>
或者这样...
($JsonObject = New-Object PSObject -Property $Serializer.DeserializeObject($JsonData))
# Results
<#
tunnels uri
------- ---
{System.Collections.Generic.Dictionary`2[System.String,System.Object]} /api/tunnels
#>
...然后点引用
$JsonObject.tunnels
# Results
<#
Key Value
--- -----
name command_line
uri /api/tunnels/command_line
public_url tcp://8.tcp.ngrok.io:12716
proto tcp
config {[addr, localhost:32400], [inspect, False]}
metrics {[conns, System.Collections.Generic.Dictionary
#>
$JsonObject.uri
# Results
<#
/api/tunnels
#>
这是 Powershell 5.1 的简单答案
$json = get-content -path "c:\path\to\json.txt" | ConvertFrom-Json
$url = $json.tunnels.public_url
更新 - Powershell 5.1 的解决方案非常简单。我单独发布了一个答案
我正在尝试我的第一个 Powershell 脚本(Windows 7 中的 2.0 版)。我正在从文件中读取以下 json 文本(该部分有效)。我想获得“public_url”的值。我在下面的脚本中遇到的错误是“
Select-Object : Property "tunnels" cannot be found
我是第一次使用 Powershell,我不太了解如何导航对象。提前致谢,
我的json文件内容:
{
"tunnels":[
{
"name":"command_line",
"uri":"/api/tunnels/command_line",
"public_url":"tcp://8.tcp.ngrok.io:12716",
"proto":"tcp",
"config":{
"addr":"localhost:32400",
"inspect":false
},
"metrics":{
"conns":{
"count":0,
"gauge":0,
"rate1":0,
"rate5":0,
"rate15":0,
"p50":0,
"p90":0,
"p95":0,
"p99":0
},
"http":{
"count":0,
"rate1":0,
"rate5":0,
"rate15":0,
"p50":0,
"p90":0,
"p95":0,
"p99":0
}
}
}
],
"uri":"/api/tunnels"
}
我的 Powershell 脚本:
function ConvertFrom-Json20([object] $item){
add-type -assembly system.web.extensions
$ps_js=new-object system.web.script.serialization.javascriptSerializer
#The comma operator is the array construction operator in PowerShell
return ,$ps_js.DeserializeObject($item)
}
$content = get-content -path "c:\path\to\json.txt"
$json = ConvertFrom-Json20($content)
$url = $json | select -expand tunnels | select public_url
echo "url=>" $url
继续我的评论。 只需使用 JSON cmdlet 升级到最新的 WinPS,不要尝试重新发明轮子。
Windows 管理框架 5.1
https://www.microsoft.com/en-us/download/details.aspx?id=54616
Windows Management Framework 5.1 includes updates to Windows PowerShell, Windows PowerShell Desired State Configuration (DSC), Windows Remote Management (WinRM), Windows Management Instrumentation (WMI). Release notes: https://go.microsoft.com/fwlink/?linkid=839460
Get-Command -Name '*json*' | Format-Table -AutoSize
# Results
<#
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet ConvertFrom-Json 3.1.0.0 Microsoft.PowerShell.Utility
Cmdlet ConvertTo-Json 3.1.0.0 Microsoft.PowerShell.Utility
#>
PowerShell 本机使用 JSON、XML,并且您可以访问所有 .Net,因此,您可以使用 JSON.
的 .Net 命名空间只需查看有关如何使用它们的帮助文件。有完整的解释和例子。
# Get specifics for a module, cmdlet, or function
(Get-Command -Name Get-Help).Parameters
(Get-Command -Name Get-Help).Parameters.Keys
Get-help -Name Get-Help -Examples
Get-help -Name Get-Help -Full
Get-help -Name Get-Help -Online
(Get-Command -Name ConvertFrom-Json).Parameters
(Get-Command -Name ConvertFrom-Json).Parameters.Keys
Get-help -Name ConvertFrom-Json -Examples
Get-help -Name ConvertFrom-Json -Full
Get-help -Name ConvertFrom-Json -Online
(Get-Command -Name ConvertTo-Json).Parameters
(Get-Command -Name ConvertTo-Json).Parameters.Keys
Get-help -Name ConvertTo-Json -Examples
Get-help -Name ConvertTo-Json -Full
Get-help -Name ConvertTo-Json -Online
根据您的评论更新
使用上面的方法,您可以通过点引用和/或索引导航 JSON 对象。
$JsonData = '
{
"tunnels":[
{
"name":"command_line",
"uri":"/api/tunnels/command_line",
"public_url":"tcp://8.tcp.ngrok.io:12716",
"proto":"tcp",
"config":{
"addr":"localhost:32400",
"inspect":false
},
"metrics":{
"conns":{
"count":0,
"gauge":0,
"rate1":0,
"rate5":0,
"rate15":0,
"p50":0,
"p90":0,
"p95":0,
"p99":0
},
"http":{
"count":0,
"rate1":0,
"rate5":0,
"rate15":0,
"p50":0,
"p90":0,
"p95":0,
"p99":0
}
}
}
],
"uri":"/api/tunnels"
}
' |
ConvertFrom-Json
$JsonData
# Results
<#
tunnels uri
------- ---
{@{name=command_line; uri=/api/tunnels/command_line; public_url=tcp://8.tcp.ngrok.io:12716; proto=tcp; config=; metrics=}} /api/tunnels
#>
$JsonData.tunnels
# Results
<#
name : command_line
uri : /api/tunnels/command_line
public_url : tcp://8.tcp.ngrok.io:12716
proto : tcp
config : @{addr=localhost:32400; inspect=False}
metrics : @{conns=; http=}
#>
$JsonData.uri
# Results
<#
/api/tunnels
#>
$JsonData.uri.Split('/')
# Results
<#
api
tunnels
#>
$JsonData.uri.Split('/')[-1]
# Results
<#
tunnels
#>
至于你的东西……好吧,它从来都不是一个对象。只是一个字符串。
这并不像你想象的那样有效
function ConvertFrom-Json20([object] $item)
{
Add-Type -Assembly System.Web.Extensions
$ps_js = New-Object System.Web.Script.Serialization.JavascriptSerializer
return
$ps_js.DeserializeObject($item)
}
($content = Get-Content -path 'D:\Scripts\json.txt')
($json = ConvertFrom-Json20($content))
# Results
<#
Nothing is returned
#>
# So this would never work
# Results
<#
$url = $json | select -expand tunnels | select public_url
echo "url=>" $url
#>
所以,读取数据并抓取字符串
(Get-Content -path 'D:\Scripts\json.txt').Trim() |
Select-String -Pattern 'uri.*'
# Results
<#
"uri":"/api/tunnels/command_line",
"uri":"/api/tunnels"
#>
((Get-Content -path 'D:\Scripts\json.txt').Trim() |
Select-String -Pattern 'uri.*')[-1] -replace '"' -split('/')
# Results
<#
uri:
api
tunnels
#>
(((Get-Content -path 'D:\Scripts\json.txt').Trim() |
Select-String -Pattern 'uri.*')[-1] -replace '"' -split('/'))[-1]
# Results
<#
tunnels
#>
要从那个 JSON 文件中获取一个对象,在 PSv2 中,你会说做这样的事情。
[void][System.Reflection.Assembly]::LoadWithPartialName('System.Web.Extensions')
$JsonData = Get-Content -Path 'D:\Scripts\Json.txt'
$Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer
($JsonObject = $Serializer.DeserializeObject($JsonData))
# Results
<#
Key Value
--- -----
tunnels {System.Collections.Generic.Dictionary`2[System.String,System.Object]}
uri /api/tunnels
#>
或者这样...
($JsonObject = New-Object PSObject -Property $Serializer.DeserializeObject($JsonData))
# Results
<#
tunnels uri
------- ---
{System.Collections.Generic.Dictionary`2[System.String,System.Object]} /api/tunnels
#>
...然后点引用
$JsonObject.tunnels
# Results
<#
Key Value
--- -----
name command_line
uri /api/tunnels/command_line
public_url tcp://8.tcp.ngrok.io:12716
proto tcp
config {[addr, localhost:32400], [inspect, False]}
metrics {[conns, System.Collections.Generic.Dictionary
#>
$JsonObject.uri
# Results
<#
/api/tunnels
#>
这是 Powershell 5.1 的简单答案
$json = get-content -path "c:\path\to\json.txt" | ConvertFrom-Json
$url = $json.tunnels.public_url