提取嵌套的JSON对象的架构

nik*_*nik 5 json nested key jq

假设这是源json文件:

{    
    "name": "tom",
    "age": 12,
    "visits": {
        "2017-01-25": 3,
        "2016-07-26": 4,
        "2016-01-24": 1
    }
}
Run Code Online (Sandbox Code Playgroud)

我想得到:

[
  "age",
  "name",
  "visits.2017-01-25",
  "visits.2016-07-26",
  "visits.2016-01-24"
]
Run Code Online (Sandbox Code Playgroud)

我可以使用:提取键jq '. | keys' file.json,但这会跳过嵌套字段。如何包括那些?

pea*_*eak 5

使用您的输入,调用:

jq 'leaf_paths | join(".")'
Run Code Online (Sandbox Code Playgroud)

产生:

"name"
"age"
"visits.2017-01-25"
"visits.2016-07-26"
"visits.2016-01-24"
Run Code Online (Sandbox Code Playgroud)

如果要包括“访问”,请使用paths。如果要将结果作为JSON数组,请用方括号将过滤器括起来:[...]

如果您的输入可能包含数组,那么除非您使用的是jq 1.6或更高版本,否则您将需要将整数索引显式转换为字符串;否则,除非您使用jq 1.6或更高版本。另外,由于leaf_paths现在已弃用,您可能要使用其def。结果:

jq 'paths(scalars) | map(tostring) | join(".")'
Run Code Online (Sandbox Code Playgroud)

全路

要包含null的路径,可以使用allpathsdefine如下:

def allpaths:
  def conditional_recurse(f):  def r: ., (select(.!=null) | f | r); r;
  path(conditional_recurse(.[]?)) | select(length > 0);
Run Code Online (Sandbox Code Playgroud)

例:

{"a": null, "b": false} | allpaths | join(".")
Run Code Online (Sandbox Code Playgroud)

产生:

"a"
"b"
Run Code Online (Sandbox Code Playgroud)

all_leaf_paths

假设jq版本为1.5或更高,我们可以all_leaf_paths通过遵循Builtins.jq中使用的策略来进行操作,即添加以下定义:

def allpaths(f):
  . as $in | allpaths | select(. as $p|$in|getpath($p)|f);

def isscalar:
  . == null or . == true or . == false or type == "number" or type == "string";

def all_leaf_paths: allpaths(isscalar);
Run Code Online (Sandbox Code Playgroud)

例:

{"a": null, "b": false, "object":{"x":0} } | all_leaf_paths | join(".")
Run Code Online (Sandbox Code Playgroud)

产生:

"a"
"b"
"object.x"
Run Code Online (Sandbox Code Playgroud)