如何从给定的JSON中生成所有唯一键路径的列表

j9per5c4  于 2023-10-21  发布在  其他
关注(0)|答案(3)|浏览(114)

我想从一个给定的JSON中生成一个所有唯一的关键路径列表,每一个都在一行中。
例如,从这个输入JSON:

  1. {
  2. "results":[
  3. {
  4. "id":306,
  5. "name":"First Company",
  6. "branches":[
  7. {
  8. "id":4191,
  9. "city":"San Francisco",
  10. "customers":[
  11. {
  12. "id":446,
  13. "name":"Big Tech 1"
  14. },
  15. {
  16. "id":447,
  17. "name":"Big Tech 2"
  18. }
  19. ]
  20. },
  21. {
  22. "id":4192,
  23. "city":"Miami",
  24. "customers":[
  25. {
  26. "id":448,
  27. "name":"Insurance Tech 1"
  28. },
  29. {
  30. "id":449,
  31. "name":"Health Tech 2"
  32. }
  33. ]
  34. }
  35. ]
  36. }
  37. ]
  38. }

我想生成这样的输出:

  1. results
  2. results.id
  3. results.name
  4. results.branches
  5. results.branches.id
  6. results.branches.city
  7. results.branches.customers
  8. results.branches.customers.id
  9. results.branches.customers.name

我在下面的命令行中挣扎,但它不起作用。

  1. jq '
  2. def path(k):
  3. if k | type == "object":
  4. reduce(.keys[] | path(.), k)
  5. else:
  6. [k]
  7. ;
  8. .[] | path(".") | flatten | sort' example.json

有什么帮助吗?

nfzehxib

nfzehxib1#

您可以mappaths只包含strings,然后使用unique删除重复项,并通过提供join项:

  1. jq -r '[paths | map(strings)] | unique[] | join(".")'
  1. results
  2. results.branches
  3. results.branches.city
  4. results.branches.customers
  5. results.branches.customers.id
  6. results.branches.customers.name
  7. results.branches.id
  8. results.id
  9. results.name

Demo
要保持文档顺序(unique也会对数组进行排序),您可以通过使用连接路径作为(定义唯一的)对象字段来消除列表的重复数据:

  1. jq -r '[paths | map(strings) | join(".") | {(.):.}] | add[]'
  1. results
  2. results.id
  3. results.name
  4. results.branches
  5. results.branches.id
  6. results.branches.city
  7. results.branches.customers
  8. results.branches.customers.id
  9. results.branches.customers.name

Demo

展开查看全部
kmbjn2e3

kmbjn2e32#

使用paths函数,过滤出对象键的数组索引,并收集唯一路径:

  1. jq '[paths(.) | map(select(type != "number")) | join(".")] | unique[]' test.json
  1. "results"
  2. "results.branches"
  3. "results.branches.city"
  4. "results.branches.customers"
  5. "results.branches.customers.id"
  6. "results.branches.customers.name"
  7. "results.branches.id"
  8. "results.id"
  9. "results.name"
093gszye

093gszye3#

下面是一个输出以下内容的解决方案,以清楚地表明数组的位置:

  1. results[]
  2. results[].branches[]
  3. results[].branches[].city
  4. results[].branches[].customers[]
  5. results[].branches[].customers[].id
  6. results[].branches[].customers[].name
  7. results[].branches[].id
  8. results[].id
  9. results[].name

这对于在操作JSON之前快速查看JSON的“形状”非常方便。
如果你在一个名为show-shape.jqdemo)的脚本中有以下代码:

  1. #! /usr/local/bin/jq -r -f
  2. def extract:
  3. [ paths
  4. | [ .[] | if type == "number" then "[]" else . end ]
  5. | join (".") ] ;
  6. def longest:
  7. . | sort_by(length) | reverse| .[0] ;
  8. def clean:
  9. [ .[] | gsub("[.][[]]"; "[]") ]
  10. | group_by(. | rtrimstr("[]"))
  11. | [ .[] | longest ];
  12. def show:
  13. extract | sort | unique | clean | .[];
  14. show

您可以按如下方式使用它:

  1. cat some.json | show-shape.jq

范例:

  1. § echo '{"x":{"a":1,"b":[{"c":1},{"c":2}],"d":{"e":1}}}' | show-shape.jq
  2. x
  3. x.a
  4. x.b[]
  5. x.b[].c
  6. x.d
  7. x.d.e

请注意x.b[].cx.d.e的显示方式之间的区别。
thuogh脚本的一个缺点是,它没有显示空数组的尾随[]

  1. § echo '{ "a" : [1] }' | show-json-shape.jq
  2. a[]
  3. § echo '{ "a" : [] }' | show-json-shape.jq
  4. a
展开查看全部

相关问题