简体   繁体   English

使用 jq/bash 迭代 JSON 数组的最佳方法

[英]Best way to iterate over JSON array with variable keys with jq/bash

I have a JSON-file like the one below:我有一个如下所示的 JSON 文件:

{
    "Results": [
        {
            "Severity": "LOW",
            "InstalledVersion": "1.21.1ubuntu2",
            "FixedVersion": "1.21.1ubuntu2.1"
        },
        {
            "Severity": "LOW",
            "InstalledVersion": "1.21.1ubuntu2"
        },
        {
            "Severity": "HIGH",
            "VulnerabilityID": "CVE-2016-2781"
        }
    ]
}

I would like to create the following JSON-file:我想创建以下 JSON 文件:

[
    {
        "Severity": "LOW",
        "InstalledVersion": "1.21.1ubuntu2",
        "FixedVersion": "1.21.1ubuntu2.1",
        "VulnerabilityID": ""
    },
    {
        "Severity": "LOW",
        "InstalledVersion": "1.21.1ubuntu2",
        "FixedVersion": "",
        "VulnerabilityID": ""
    },
    {
        "Severity": "HIGH",
        "InstalledVersion": "",
        "FixedVersion": "",
        "VulnerabilityID": "CVE-2016-2781"
    }
]

I have tried iterating over the first JSON-file, but when I do so in the following way, I get random parsing errors (with the real JSON-file I am working with).我尝试遍历第一个 JSON 文件,但是当我按照以下方式这样做时,我得到随机解析错误(使用我正在处理的真实 JSON 文件)。 So I think there is something off about the piping that I am doing.所以我认为我正在做的管道有些问题。

jq -c '.Results[]' my.json | while read i; do
    echo $i;
done

In the JSON-file I am working with jq -c '.Results[]' works perfectly, but when I do jq operations on the resulting $i while iterating, I suddently get several parsing errors.在我使用jq -c '.Results[]'的 JSON 文件中,效果很好,但是当我在迭代时对生成的$i进行jq操作时,我突然遇到了几个解析错误。

Is there better way to iterate over key-value-pairs in a JSON-file?有没有更好的方法来遍历 JSON 文件中的键值对? Ofcause I could just install Python/R and do the typical drill, but I would really like for this to work in a shell script. Ofcause 我可以只安装 Python/R 并进行典型的练习,但我真的希望它能在 shell 脚本中工作。

You can use + to add two objects together by combining their fields;您可以使用+通过组合它们的字段来将两个对象加在一起; if both objects have the same one the value of the right hand one is used.如果两个对象具有相同的对象,则使用右手对象的值。 So if you make your existing object the RHS:因此,如果您将现有的 object 设为 RHS:

 jq '[ .Results[] | {Severity:"", InstalledVersion:"", FixedVersion:"", VulnerabilityID:""} + . ]' input.json   
[
  {
    "Severity": "LOW",
    "InstalledVersion": "1.21.1ubuntu2",
    "FixedVersion": "1.21.1ubuntu2.1",
    "VulnerabilityID": ""
  },
  {
    "Severity": "LOW",
    "InstalledVersion": "1.21.1ubuntu2",
    "FixedVersion": "",
    "VulnerabilityID": ""
  },
  {
    "Severity": "HIGH",
    "InstalledVersion": "",
    "FixedVersion": "",
    "VulnerabilityID": "CVE-2016-2781"
  }
]

One more variation另一种变化

jq '[
    .Results[]
    | .FixedVersion //= ""
    | .VulnerabilityID //= ""
    | .InstalledVersion //= ""
]' file.json

Another way of adding the fallbacks to a empty string:将回退添加到空字符串的另一种方法:

[ .Results[] | . + { VulnerabilityID: (.VulnerabilityID // ""), FixedVersion: (.FixedVersion // ""), InstalledVersion: (.InstalledVersion // "") } ]
[
  {
    "Severity": "LOW",
    "InstalledVersion": "1.21.1ubuntu2",
    "FixedVersion": "1.21.1ubuntu2.1",
    "VulnerabilityID": ""
  },
  {
    "Severity": "LOW",
    "InstalledVersion": "1.21.1ubuntu2",
    "VulnerabilityID": "",
    "FixedVersion": ""
  },
  {
    "Severity": "HIGH",
    "VulnerabilityID": "CVE-2016-2781",
    "FixedVersion": "",
    "InstalledVersion": ""
  }
]

Online demo在线演示

A more generic approach:更通用的方法:

jq '.Results |
    (map(keys)|add|unique|map({key:.,value:""})|from_entries) as $default |
    map($default + .)
   ' input.json

Explanations:说明:

1) map(keys)|add|unique
   gets all the keys. If it's a subset you are interested, you can substitute it with :
   ["FixedVersion", "VulnerabilityID", "InstalledVersion"]
2) map({key:.,value:""})|from_entries) as $default
   constructs a default object with all (or selected) keys.
3) $default + .
   adds a key from default object if the key does not exist.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM