【问题标题】:PowerShell : retrieve JSON object by field valuePowerShell:按字段值检索 JSON 对象
【发布时间】:2013-05-10 15:17:25
【问题描述】:

考虑采用这种格式的 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 表达式)。

【问题讨论】:

    标签: json powershell powershell-3.0


    【解决方案1】:
    $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。因此我需要一些方法来匹配名称字段上的对象。跨度>
    • $x.Stuffs |其中 { $_.Name -eq "飞镖" }
    • 不要挑剔但是...这不只是一种“美化”的蛮力吗?这不像 Where-Object 不像 foreach 那样循环遍历集合。事实上,我认为 Where-Object 无论如何都使用了 foreach。
    • 除非 PS 出于某种原因会在任何 JSON 结构中的 每个 键上保留哈希表索引,否则此处无法绕过“蛮力”。你可以用其他语言的语法来隐藏它,但仅此而已。
    【解决方案2】:

    我刚刚在这里问了同样的问题: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 个名称-值对,否则此解决方案效果很好。然后powershell失败:PS > $el = ConvertFrom-Json "{ }"PS> $el.psobject.properties.nameThe property 'name' cannot be found on this object. Verify that the property exists.
    • 另一个警告:如果 JSON 对象(比如 $el)有 1 个名称-值对,则 $el.psobject.properties.name 返回名称的字符长度而不是名称的数量-值对(即 1)
    【解决方案3】:

    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!"}
      

      这是基于此accessing values in powershell SO question . powershell 是不是很棒!

      【讨论】:

        【解决方案5】:

        关于 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,那么据我所知,这是最好的方法。

        【讨论】:

          【解决方案6】:

          这是我的 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
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-01
            • 2013-01-19
            • 1970-01-01
            • 1970-01-01
            • 2018-06-07
            相关资源
            最近更新 更多