我想使用 探索任意文档jq
。为此,我想限制jq
文档的深度,只显示第一个n
(例如 3 个)级别。
假设我有以下 JSON 文档:
{
"a": {
"b": {
"c": {
"d": {
"e": "foo"
}
}
}
},
"f": {
"g": {
"h": {
"i": {
"j": "bar"
}
}
}
},
"k": {
"l": {
"m": {
"n": {
"o": "baz"
}
}
}
}
}
我期待结果
{
"a": {
"b": {
"c": {}
}
},
"f": {
"g": {
"h": {}
}
},
"k": {
"l": {
"m": {}
}
}
}
如果我事先知道文档的结构,那么这是一项相当简单的任务,但我常常不知道。这就是为什么我希望能够jq
仅显示文档结构的前 n 层,这可能是字典和数组的任意嵌套。
一个更复杂的例子可能是:
[
{ "a": { "b": { "c": { "d": { "e": "foo"}}}}},
{ "f": [ { "g": "foo"}]},
[ "h", "i", "j" ]
]
我期望结果的地方
[
{ "a": { "b": {}},
{ "f": [{}]},
[ "h", "i", "j" ]
]
我可以做jq
这个吗?
答案1
del
将函数与数组/对象值迭代器结合起来.[]?
删除第四层嵌套的任何键/值似乎给出了您正在寻找的结果:
$ jq 'del(.[]?[]?[]?[]?)' <<'EOT'
[
{ "a": { "b": { "c": { "d": { "e": "foo"}}}}},
{ "f": [ { "g": "foo"}]},
[ "h", "i", "j" ]
]
EOT
[
{
"a": {
"b": {}
}
},
{
"f": [
{}
]
},
[
"h",
"i",
"j"
]
]
需要迭代器过滤器.[]?
的版本来防止在尝试迭代不是数组或对象的项时出现抱怨。.[]
jq
老实说,我.[][]
在文档中的任何地方都找不到上面显示的形式(基本上:)中对数组/对象迭代器过滤器的任何直接提及。一个不太简洁但记录清晰的版本是:
$ jq 'del(.[]? | .[]? | .[]? | .[]?)' ...
答案2
使用path(..)
您可以为给定文档生成所有可能的路径表达式。然后您可以使用例如选择太长的那些select(length > 3)
。这些可以用 删除delpaths()
。
这样做的好处是允许我们编写一个看起来简洁的表达式,该表达式可以轻松地用单个整数进行参数化(可以将其传递给jq
with --argjson
),但该path(..)
表达式同时不必要地“重”(产生每一个文档中的路径)。
$ jq 'delpaths([path(..) | select(length > 3)])' file
{
"a": {
"b": {
"c": {}
}
},
"f": {
"g": {
"h": {}
}
},
"k": {
"l": {
"m": {}
}
}
}
使用问题末尾的示例文档进行测试:
$ jq . file
[
{
"a": {
"b": {
"c": {
"d": {
"e": "foo"
}
}
}
}
},
{
"f": [
{
"g": "foo"
}
]
},
[
"h",
"i",
"j"
]
]
$ jq --argjson d 1 'delpaths([path(..) | select(length > $d)])' file
[
{},
{},
[]
]
$ jq --argjson d 2 'delpaths([path(..) | select(length > $d)])' file
[
{
"a": {}
},
{
"f": []
},
[
"h",
"i",
"j"
]
]
$ jq --argjson d 3 'delpaths([path(..) | select(length > $d)])' file
[
{
"a": {
"b": {}
}
},
{
"f": [
{}
]
},
[
"h",
"i",
"j"
]
]
答案3
此方法可能并不理想,因为它依赖于可能在 jq 版本之间发生变化的空格,但从某种意义上说,它是一种强大的方法,它可以与其他工具一起应用于类似的情况。
jq 完成漂亮的打印后,它将在 json 树下方的元素前面添加空格。因此,如果您只是对具有一定数量前导空格的行执行反向 grep,则可以删除超出一定深度的任何元素。在下面的示例中,我删除了深度等于或大于 4 的元素,与您的示例类似。
grifball@grifball-Computer:~$ cat limit-output.json
{"a":{"b":{"c":{"d":{"e":"foo"}}}},"f":{"g":{"h":{"i":{"j":"bar"}}}},"k":{"l":{"m":{"n":{"o":"baz"}}}}}
grifball@grifball-Computer:~$ cat limit-output.json | jq
{
"a": {
"b": {
"c": {
"d": {
"e": "foo"
}
}
}
},
"f": {
"g": {
"h": {
"i": {
"j": "bar"
}
}
}
},
"k": {
"l": {
"m": {
"n": {
"o": "baz"
}
}
}
}
}
grifball@grifball-Computer:~$ cat limit-output.json | jq | grep -v '^\s\{8\}'
{
"a": {
"b": {
"c": {
}
}
},
"f": {
"g": {
"h": {
}
}
},
"k": {
"l": {
"m": {
}
}
}
}