使用唯一标识符访问 json 对象中的字段

access fields in json object with unique identifiers

我无法理解 jq。我什至无法表达我想学的东西。

我想我想要一个通配符?我的愿望是,给出这样的 json 片段:

{
  "logs": {
    "-MnpQaRONGXz9tff-W": {
      "points": 10,
      "type": "signup"
    },
    "-N5qlX1mQ3SYA9RXdE": {
      "points": 15,
      "type": "welcome"
    },
    "-N5rx8PAcNgWu25zRf": {
      "points": 5,
      "type": "vote"
    },
    "-N5s29TyZ33snUqC5X": {
      "points": 5,
      "type": "vote"
    }
  },
  "total": 35
}

计算某个类型出现了多少次,甚至可以将所有类型输出到一个文件中。

这完全行不通(在简化的示例中没有意义):

cat test.json | jq '.logs | * | .type'

会给我一个简单的对象或类型列表。

不是仅 jq 的答案,但您可以获得所有 type 字段的列表,然后通过管道将其通过 uniq -c 以获得计数。

$ jq '.logs[] | .type' tmp.json | uniq -c
    1 signup
    1 welcome
    2 vote

获取所有对象的所有 "type" 值的流,无论嵌套有多深:

 .. | select(.type?) | .type

在您的具体情况下,以下内容就足够了:

.[] | select(type == "object") | .[].type

制作表格:

def tabulate: reduce .[] as $i ({}; .[$i] += 1 );

[.[] | select(type == "object") | .[].type] | tabulate

根据您的输入,输出将是: { "signup": 1, "welcome": 1, "vote": 2 }

这是一个使用 tostreamreduce

的解决方案
reduce (tostream|select(length==2)) as [$p,$v] (
  {}
; if $p[-1] == "type" then .[$v] += 1 else . end  
)

输出样本数据

{
  "signup": 1,
  "welcome": 1,
  "vote": 2
}