使用 jq 从 json 个数据结构中提取标签

Extract tags from json datastructures using jq

我有多个 JSON 文件,如下所示:

{
  "object1": {
    "tags": ["A"],

    "something": "else",
    "other": "data"
  },
  "object2": {
    "tags": ["A", "B"]
  }
}

{
  "object3": {
    "tags": ["C"],

    "something": "else",
    "other": "data"
  },
  "object4": {
    "tags": ["A"]
  }
}

保证所有对象 (object1 - object4) 的键在所有文件中都是唯一的。

我需要生成一个不同的 json 文件,这将是一个使用过的 tag 的数组,每个标签都会有 object 使用它的额外信息:

[
  { 
    "tag": "A",
    "objects": ["object1", "object2", "object4"]
  },
  { 
    "tag": "B",
    "objects": ["object2"]
  },
  { 
    "tag": "C",
    "objects": ["object3"]
  }
]

此输出数组中标签的顺序无关紧要。

到目前为止,我有:cat *.json | jq -s add | jq '[.[].tags[]] | unique',它为我提供了所有文件中使用的标签数组,但我不太清楚如何获取这些标签的 object 列表。我怀疑这不是一个正确的方法,因为我在这个转换过程中丢失了一些信息(标签的来源)。

任何有关 jq 表达式的帮助将不胜感激。谢谢。

一种方法是 reduce 使用 to_entries

输入
jq -s '
  add | reduce to_entries[] as $e ({}; .[$e.value.tags[]] += [$e.key])
' *.json

这会给你这样的结构

{
  "A": [
    "object1",
    "object2",
    "object4"
  ],
  "B": [
    "object2"
  ],
  "C": [
    "object3"
  ]
}

Demo

然后将其转换为您想要的结构,附加另一个 to_entries

jq -s '
  add | reduce to_entries[] as $e ({}; .[$e.value.tags[]] += [$e.key])
  | to_entries | map({tag:.key, objects:.value})
' *.json
[
  {
    "tag": "A",
    "objects": [
      "object1",
      "object2",
      "object4"
    ]
  },
  {
    "tag": "B",
    "objects": [
      "object2"
    ]
  },
  {
    "tag": "C",
    "objects": [
      "object3"
    ]
  }
]

Demo