PowerShell:按字段值检索JSON对象


73

考虑以下格式的JSON:

"Stuffs": [
    {
        "Name": "Darts",
        "Type": "Fun Stuff"
    },
    {
        "Name": "Clean Toilet",
        "Type": "Boring Stuff"
    }
]

在PowerShell 3中,我们可以获得Stuffs的列表:

$JSON = Get-Content $jsonConfigFile | Out-String | ConvertFrom-Json

假设我们不知道列表的确切内容,包括对象的顺序,我们如何检索名称字段具有特定值的对象?

蛮力,我们可以遍历列表:

foreach( $Stuff in $JSON.Stuffs ) { 

但我希望存在更直接的机制(类似于C#中的Lync或Lambda表达式)。

Answers:


96
$json = @"
{
"Stuffs": 
    [
        {
            "Name": "Darts",
            "Type": "Fun Stuff"
        },

        {
            "Name": "Clean Toilet",
            "Type": "Boring Stuff"
        }
    ]
}
"@

$x = $json | ConvertFrom-Json

$x.Stuffs[0] # access to Darts
$x.Stuffs[1] # access to Clean Toilet
$darts = $x.Stuffs | where { $_.Name -eq "Darts" } #Darts

谢谢大卫。我已经修正了我的问题,使其更加清楚。您的答案将不起作用,因为代码不会提前知道JSON的结构。飞镖可能在插槽0中,清洁厕所在插槽1中,但是飞镖可能在插槽0中,飞镖在插槽1中。因此,我需要某种方式来匹配名称字段上的对象。
BaltoStar 2013年

12
$ x。东西| 其中{$ _。Name -eq“ Darts”}
David Brabant

不要挑剔,但是...这不只是一种“荣耀的”蛮力吗?就像whereeach一样,Where-Object并没有遍历整个集合。实际上,我认为Where-Object无论如何都使用foreach。
Tom Padilla

36

我在这里问了同样的问题:https : //stackoverflow.com/a/23062370/3532136 它有一个很好的解决方案。希望对您有所帮助。在简历中,您可以使用以下命令:

在我的情况下,Json文件称为jsonfile.json

{
    "CARD_MODEL_TITLE": "OWNER'S MANUAL",
    "CARD_MODEL_SUBTITLE": "Configure your download",
    "CARD_MODEL_SELECT": "Select Model",
    "CARD_LANG_TITLE": "Select Language",
    "CARD_LANG_DEVICE_LANG": "Your device",
    "CARD_YEAR_TITLE": "Select Model Year",
    "CARD_YEAR_LATEST": "(Latest)",
    "STEPS_MODEL": "Model",
    "STEPS_LANGUAGE": "Language",
    "STEPS_YEAR": "Model Year",
    "BUTTON_BACK": "Back",
    "BUTTON_NEXT": "Next",
    "BUTTON_CLOSE": "Close"
}

码:

$json = (Get-Content "jsonfile.json" -Raw) | ConvertFrom-Json

$json.psobject.properties.name

输出:

CARD_MODEL_TITLE
CARD_MODEL_SUBTITLE
CARD_MODEL_SELECT
CARD_LANG_TITLE
CARD_LANG_DEVICE_LANG
CARD_YEAR_TITLE
CARD_YEAR_LATEST
STEPS_MODEL
STEPS_LANGUAGE
STEPS_YEAR
BUTTON_BACK
BUTTON_NEXT
BUTTON_CLOSE

感谢mjolinor


警告:JSON对象可以包含0个或多个名称/值对。除非对象具有0个名称/值对,否则此解决方案效果很好。然后PS > $el = ConvertFrom-Json "{ }" PS> $el.psobject.properties.name The property 'name' cannot be found on this object. Verify that the property exists.
Powershell

另一个警告:如果一个JSON对象(例如$ el)具有1个名称-值对,则$ el.psobject.properties.name返回以字符为单位的名称长度,而不是名称-值对的数量(即1)
NoBrassRing

19

大卫·布拉本特(David Brabant)的回答使我找到了我所需要的东西,并增加了以下内容:

x.Stuffs | where { $_.Name -eq "Darts" } | Select -ExpandProperty Type

4

怎么样:

$json=Get-Content -Raw -Path 'my.json' | Out-String | ConvertFrom-Json
$foo="TheVariableYourUsingToSelectSomething"
$json.SomePathYouKnow.psobject.properties.Where({$_.name -eq $foo}).value

从json结构中选择

{"SomePathYouKnow":{"TheVariableYourUsingToSelectSomething": "Tada!"}

这是基于Powershell SO问题中的访问值 。Powershell太棒了!


2

关于PowerShell 5.1(在PowerShell 7中这要容易得多)...

假设我们有一个文件jsonConfigFile.json,该文件的名称来自您的帖子,内容如下:

{
    "Stuffs": [
        {
            "Name": "Darts",
            "Type": "Fun Stuff"
        },
        {
            "Name": "Clean Toilet",
            "Type": "Boring Stuff"
        }
    ]
}

这将根据JSON文件创建有序哈希表,以帮助简化检索过程:

$json = [ordered]@{}

(Get-Content "jsonConfigFile.json" -Raw | ConvertFrom-Json).PSObject.Properties |
    ForEach-Object { $json[$_.Name] = $_.Value }

$json.Stuffs会列出一个不错的哈希表,但是从这里开始变得有点复杂。假设您希望将Type密钥的值与Clean Toilet密钥相关联,则可以像这样检索它:

$json.Stuffs.Where({$_.Name -eq "Clean Toilet"}).Type

这很痛苦,但是如果您的目标是在准系统Windows 10安装上使用JSON,那么据我所知,这是最好的方法。


-1

这是我的json数据:

[
   {
      "name":"Test",
      "value":"TestValue"
   },
   {
      "name":"Test",
      "value":"TestValue"
   }
]

Powershell脚本:

$data = Get-Content "Path to json file" | Out-String | ConvertFrom-Json

foreach ($line in $data) {
     $line.name
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.