首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PowerShell中正确初始化JSON的问题

在PowerShell中正确初始化JSON的问题
EN

Stack Overflow用户
提问于 2020-10-20 18:47:37
回答 2查看 44关注 0票数 1

我很难理解JSON在PowerShell中是如何工作的……我想创建和实现一个JSON,但我认为我做错了什么。

此代码不起作用:

代码语言:javascript
复制
$json = @"
{ 
    "Volume" : [
    ]
}
"@ | ConvertFrom-Json | Select-Object -Expand Volume


foreach ($i in 0..2) {
    $blockvalue = @"
        { "UUID" : "uuid-$($i)",
            "Details" : [ { "Name" : "Name-$($i)" }, { "SVM" : "SVM-$($i) " }, { "LastSnapshot" : "snap-$($i)" }, { "Date" : "date-$($i) " } ] }
"@
    $json += (ConvertFrom-Json -InputObject $blockvalue)
}



$json | Select UUID,@{Name="Volume";E={$_.Details | Select -Expand Name}},@{Name="SVM";E={$_.Details | Select -Expand SVM}},@{Name="Date";E={$_.Details | Select -Expand Date}},@{Name="LastSnapshot";E={$_.Details | Select -Expand LastSnapshot}} | FT

输出:

代码语言:javascript
复制
Method invocation failed because [System.Management.Automation.PSObject] does 
not contain a method named 'op_Addition'.
At line:14 char:5
+     $json += (ConvertFrom-Json -InputObject $blockvalue)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], Runtime 
   Exception
    + FullyQualifiedErrorId : MethodNotFound
 
Method invocation failed because [System.Management.Automation.PSObject] does 
not contain a method named 'op_Addition'.
At line:14 char:5
+     $json += (ConvertFrom-Json -InputObject $blockvalue)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], Runtime 
   Exception
    + FullyQualifiedErrorId : MethodNotFound
 

UUID             Volume           SVM             Date            LastSnapshot   
----             ------           ---             ----            ------------   
uuid-0           Name-0           SVM-0           date-0          snap-0

所以我找到了一个“解决方案”,我使用下面的代码,它是工作,但它并不干净(最糟糕的是,它不知道为什么它是工作的):

代码语言:javascript
复制
$json2 = @"
{ 
    "Volume" : [
        {},
        {}
    ]
}
"@ | ConvertFrom-Json | Select-Object -Expand Volume


foreach ($i in 0..2) {
    $blockvalue = @"
        { "UUID" : "uuid-$($i)",
            "Details" : [ { "Name" : "Name-$($i)" }, { "SVM" : "SVM-$($i) " }, { "LastSnapshot" : "snap-$($i)" }, { "Date" : "date-$($i) " } ] }
"@
    $json2 += (ConvertFrom-Json -InputObject $blockvalue)
}

$json2 | Select UUID,@{Name="Volume";E={$_.Details | Select -Expand Name}},@{Name="SVM";E={$_.Details | Select -Expand SVM}},@{Name="Date";E={$_.Details | Select -Expand Date}},@{Name="LastSnapshot";E={$_.Details | Select -Expand LastSnapshot}} | FT

输出:

代码语言:javascript
复制
UUID             Volume           SVM             Date            LastSnapshot   
----             ------           ---             ----            ------------   
                                                                                 
                                                                                 
uuid-0           Name-0           SVM-0           date-0          snap-0         
uuid-1           Name-1           SVM-1           date-1          snap-1         
uuid-2           Name-2           SVM-2           date-2          snap-2

看看我所期待的:

代码语言:javascript
复制
UUID             Volume           SVM             Date            LastSnapshot   
----             ------           ---             ----            ------------   
uuid-0           Name-0           SVM-0           date-0          snap-0         
uuid-1           Name-1           SVM-1           date-1          snap-1         
uuid-2           Name-2           SVM-2           date-2          snap-2

我相信这很容易解决,但我没有PS的天赋…

提前感谢您的帮助:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-20 19:36:25

除了您正在使用的脚本的复杂性之外,只需声明一个数组,以便可以向其中添加项:

代码语言:javascript
复制
$json2 = @()

foreach ($i in 0..2) {
    $blockvalue = @"
        { "UUID" : "uuid-$($i)",
            "Details" : [ { "Name" : "Name-$($i)" }, { "SVM" : "SVM-$($i) " }, { "LastSnapshot" : "snap-$($i)" }, { "Date" : "date-$($i) " } ] }
"@
    $json2 += (ConvertFrom-Json -InputObject $blockvalue)
}

$json2 | 
Select-Object UUID,
    @{ Name = "Volume";       Expression = { $_.Details | Select-Object -Expand Name         } },
    @{ Name = "SVM";          Expression = { $_.Details | Select-Object -Expand SVM          } },
    @{ Name = "Date";         Expression = { $_.Details | Select-Object -Expand Date         } },
    @{ Name = "LastSnapshot"; Expression = { $_.Details | Select-Object -Expand LastSnapshot } } |
Format-Table
票数 0
EN

Stack Overflow用户

发布于 2020-10-22 03:07:04

通常,使用+=来追加数组是一种不好的做法。这种方法会创建一个新的数组。原始数组的内容加上右操作数将被复制到新数组中。对于小任务,这没什么大不了的,但对于较大的数据集,它会导致指数级的性能下降。

对于快速POC或控制台类型以外的任何工作,我建议您避免在阵列上使用+=。最常见的方法,通常也是最快的方法是让PowerShell为您累积输出。对Bernard's fine answer的调整:

代码语言:javascript
复制
$json2 = 
foreach ($i in 0..2) {
 @"
{ "UUID" : "uuid-$($i)",
    "Details" : [ { "Name" : "Name-$($i)" }, { "SVM" : "SVM-$($i) " }, { "LastSnapshot" : "snap-$($i)" }, { "Date" : "date-$($i) " } ] }
"@ | ConvertFrom-Json     
}

$json2 | 
Select-Object UUID,
    @{ Name = "Volume";       Expression = { $_.Details | Select-Object -ExpandProperty Name         } },
    @{ Name = "SVM";          Expression = { $_.Details | Select-Object -ExpandProperty SVM          } },
    @{ Name = "Date";         Expression = { $_.Details | Select-Object -ExpandProperty Date         } },
    @{ Name = "LastSnapshot"; Expression = { $_.Details | Select-Object -ExpandProperty LastSnapshot } } | 
Format-Table

我想建议更多的语法糖;通常您不需要在平面字符串上重复调用Select-Object -ExpandProperty ...。这段代码可能看起来更像

代码语言:javascript
复制
$json2 | 
Select-Object UUID,
    @{ Name = "Volume";       Expression = { $_.Details.Name         } },
    @{ Name = "SVM";          Expression = { $_.Details.SVM          } },
    @{ Name = "Date";         Expression = { $_.Details.Date         } },
    @{ Name = "LastSnapshot"; Expression = { $_.Details.LastSnapshot } } | 
Format-Table

然而,这产生了不同寻常的结果。展开上述属性会产生类似于Name-0、Null、Null、Null的数组。我将其追溯到JSON文本/结构。我不确定这是不是您的意图,但生成的对象结构如下:

代码语言:javascript
复制
@{UUID=uuid-0; Details=System.Object[]}
|- UUID = uuid-0
|  |- Length = 6
|- Details
| |- Details[0] = @{Name=Name-0}
| |  |- Name = Name-0
| |- Details[1] = @{SVM=SVM-1}
| |  |- SVM = SVM-1
| |- Details[2] = @{LastSnapShot=LastSnapShot-2}
| |  |- LastSnapShot = LastSnapShot-2
| |- Details[3] = @{Date=Date-3}
|    |- Date = Date-3

Details属性是一个对象数组,包含一系列更多的对象,每个对象都有一个单独的属性,分别是Name、SVM等。我认为这样做的目的可能是让细节成为一个具有名称、支持向量机、LastSnapShot和日期作为属性的对象。如果这是正确的,JSON的创建可能看起来更像下面,其中只有一组外部的花括号。

代码语言:javascript
复制
$json2 = 
ForEach( $i in 0..2 ) {
@"
{ "UUID" : "uuid-$($i)",
    "Details" : [ { "Name" : "Name-$($i)", "SVM" : "SVM-$($i) ", "LastSnapshot" : "snap-$($i)", "Date" : "date-$($i) " } ] }
"@ | ConvertFrom-Json     
}

$json2 | 
Select-Object UUID,
    @{ Name = "Volume";       Expression = { $_.Details.Name         } },
    @{ Name = "SVM";          Expression = { $_.Details.SVM          } },
    @{ Name = "Date";         Expression = { $_.Details.Date         } },
    @{ Name = "LastSnapshot"; Expression = { $_.Details.LastSnapshot } } | 
Format-Table

在这种情况下,可以使用更简洁且可能更快的属性展开语法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64443568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档