从对象的嵌套数组中获取数据

时间:2020-02-26 09:53:26

标签: jquery arrays json bash dictionary

我正在尝试解析JSON文件,以从同一文件中的字典中获取特定的值和.items []名称。

Source.json文件:https://jqplay.org/s/0-o4HOox-K

{
  "name": "ABC Company",
  "assetbase": [{
    "name": "Added assets from API",
    "type": "access-section",
    "assetbase": [{
      "name": "Database A",
      "asset-number": 1,
      "items": ["0ABC-001", "0ABC-003", "0ABC-004"]
    }, {
      "name": "Database B",
      "asset-number": 2,
      "items": ["0ABC-001"]
    }, {
      "name": "Database C",
      "asset-number": 3,
      "items": ["0ABC-002", "0ABC-003"]
    }]
  }],
  "objects-dictionary": [{
    "uid": "0ABC-001",
    "name": "Cluster A"
  }, {
    "uid": "0ABC-002",
    "name": "Cluster B"

  }, {
    "uid": "0ABC-003",
    "name": "Unit-001"
  }, {
    "uid": "0ABC-004",
    "name": "Unit-002"
  }]
}

预期输出:

"Database A","Cluster A";"Unit-001";"Unit-002"
"Database B","Cluster A"
"Database C","Cluster B";"Unit-001"

我环顾了类似的线程,并在jqplay上进行了随机测试,但根本无法获得输出。

3 个答案:

答案 0 :(得分:2)

jq解决方案:

jq -r '([(."objects-dictionary"[] | {key:.uid, value:.name})] | from_entries
       ) as $obj
       | .assetbase[] | .assetbase[]
       | [.name, (.items[] as $i | $obj[$i])]
       | @csv' < file.json

它仅使用逗号,不使用分号,但是我担心jq无法做到这一点。

答案 1 :(得分:0)

使用 jq link),您可以轻松地解析.json文件。

这是一个非常接近您的解决方案:

$ jq -r '.assetbase[].assetbase[] | .name' test.json |
    while read name; do echo -ne "\"$name\"," ;
      jq -r --arg name "$name" '.assetbase[].assetbase[] |
      select (.name | contains($name)) | .items[]' test.json |
      while read uid; do
        jq -r --arg uid $uid '."objects-dictionary"[] |
        select (.uid | contains($uid)) | .name' test.json |
        while read oname; do echo -ne "\"$oname\";" ; done;
      done; echo -ne "\n" ;
    done

"Database A","Cluster A";"Unit-001";"Unit-002";
"Database B","Cluster A";
"Database C","Cluster B";"Unit-001";

您可以通过常见的软件包管理器轻松安装它: sudo yum install -y jq用于基于RPM的发行版(如RedHat),或sudo apt-get install -y jq对于基于Debian的发行版(Ubuntu等);

答案 2 :(得分:0)

这不是bash解决方案,而是JS解决方案。

下面的代码片段创建了一个以数据库名称作为键的对象(在控制台中查看):

const data = {
  "name": "ABC Company",
  "assetbase": [{
    "name": "Added assets from API",
    "type": "access-section",
    "assetbase": [{
      "name": "Database A",
      "asset-number": 1,
      "items": ["0ABC-001", "0ABC-003", "0ABC-004"]
    }, {
      "name": "Database B",
      "asset-number": 2,
      "items": ["0ABC-001"]
    }, {
      "name": "Database C",
      "asset-number": 3,
      "items": ["0ABC-002", "0ABC-003"]
    }]
  }],
  "objects-dictionary": [{
    "uid": "0ABC-001",
    "name": "Cluster A"
  }, {
    "uid": "0ABC-002",
    "name": "Cluster B"

  }, {
    "uid": "0ABC-003",
    "name": "Unit-001"
  }, {
    "uid": "0ABC-004",
    "name": "Unit-002"
  }]
}

const mapAssets = (assetbase, dictionary) => {
  const ret = assetbase.reduce((a, c) => {
    if (typeof a[c.name] === "undefined") a[c.name] = []
    a[c.name].push(c.name)
    c.items.forEach(e => {
      const {
        name
      } = dictionary.find(el => {
        return el.uid === e
      })
      a[c.name].push(name)
    })
    return a
  }, {})
  return ret
}

const mapped = mapAssets(data.assetbase[0].assetbase, data["objects-dictionary"])

console.log('mapped:', mapped)