如何使用 jq 获取找到的值的索引路径?
How to get the index path of found values using jq?
假设我有一个 JSON 这样的:
{
"json": [
"a",
[
"b",
"c",
[
"d",
"foo",
1
],
[
[
42,
"foo"
]
]
]
]
}
我想要一个包含 foo
:
的 jq
索引路径数组
[
".json[1][2][1]",
".json[1][3][0][1]"
]
我可以使用 jq
实现吗?如何实现?
我尝试 recurse | .foo
先获取匹配项,但收到错误消息:Cannot index array with string "foo"
.
首先,我不确定获取jq
程序数组的目的是什么。虽然存在这样做的方法,但很少有必要; jq 不提供任何类型的 eval
命令。
jq有路径的概念,是一个字符串和数字组成的数组,表示一个元素在JSON中的位置;这相当于您预期输出中的字符串。例如,".json[1][2][1]"
将表示为 ["json", 1, 2, 1]
。标准库包含几个使用此概念操作的函数,例如 getpath
、setpath
、paths
和 leaf_paths
.
因此,我们可以获得给定 JSON 中的所有叶路径并遍历它们,select 那些它们在输入 JSON 中的值为 "foo" 的路径,并从中生成一个数组:
jq '[paths as $path | select(getpath($path) == "foo") | $path]'
这将 return,对于您给定的输入,以下输出:
[
["json", 1, 2, 1],
["json", 1, 3, 0, 1]
]
现在,虽然这不是必需的,而且很可能表明您正在以错误的方式解决您所面临的任何问题,但可以将这些数组转换为您寻求的 jq 路径字符串通过以下脚本转换每个路径:
".\(map("[\(tojson)]") | join(""))"
完整的脚本因此是:
jq '[paths as $path | select(getpath($path) == "foo") | $path | ".\(map("[\(tojson)]") | join(""))"]'
其输出为:
[
".[\"json\"][1][2][1]",
".[\"json\"][1][3][0][1]"
]
可以进一步调整 Santiago 的优秀程序以生成请求格式的输出:
def jqpath:
def t: test("^[A-Za-z_][A-Za-z0-9_]*$");
reduce .[] as $x
("";
if ($x|type) == "string"
then . + ($x | if t then ".\(.)" else ".[" + tojson + "]" end)
else . + "[\($x)]"
end);
[paths as $path | select( getpath($path) == "foo" ) | $path | jqpath]
jq -f wrangle.jq input.json
[
".json[1][2][1]",
".json[1][3][0][1]"
]
假设我有一个 JSON 这样的:
{
"json": [
"a",
[
"b",
"c",
[
"d",
"foo",
1
],
[
[
42,
"foo"
]
]
]
]
}
我想要一个包含 foo
:
jq
索引路径数组
[
".json[1][2][1]",
".json[1][3][0][1]"
]
我可以使用 jq
实现吗?如何实现?
我尝试 recurse | .foo
先获取匹配项,但收到错误消息:Cannot index array with string "foo"
.
首先,我不确定获取jq
程序数组的目的是什么。虽然存在这样做的方法,但很少有必要; jq 不提供任何类型的 eval
命令。
jq有路径的概念,是一个字符串和数字组成的数组,表示一个元素在JSON中的位置;这相当于您预期输出中的字符串。例如,".json[1][2][1]"
将表示为 ["json", 1, 2, 1]
。标准库包含几个使用此概念操作的函数,例如 getpath
、setpath
、paths
和 leaf_paths
.
因此,我们可以获得给定 JSON 中的所有叶路径并遍历它们,select 那些它们在输入 JSON 中的值为 "foo" 的路径,并从中生成一个数组:
jq '[paths as $path | select(getpath($path) == "foo") | $path]'
这将 return,对于您给定的输入,以下输出:
[
["json", 1, 2, 1],
["json", 1, 3, 0, 1]
]
现在,虽然这不是必需的,而且很可能表明您正在以错误的方式解决您所面临的任何问题,但可以将这些数组转换为您寻求的 jq 路径字符串通过以下脚本转换每个路径:
".\(map("[\(tojson)]") | join(""))"
完整的脚本因此是:
jq '[paths as $path | select(getpath($path) == "foo") | $path | ".\(map("[\(tojson)]") | join(""))"]'
其输出为:
[
".[\"json\"][1][2][1]",
".[\"json\"][1][3][0][1]"
]
可以进一步调整 Santiago 的优秀程序以生成请求格式的输出:
def jqpath:
def t: test("^[A-Za-z_][A-Za-z0-9_]*$");
reduce .[] as $x
("";
if ($x|type) == "string"
then . + ($x | if t then ".\(.)" else ".[" + tojson + "]" end)
else . + "[\($x)]"
end);
[paths as $path | select( getpath($path) == "foo" ) | $path | jqpath]
jq -f wrangle.jq input.json
[
".json[1][2][1]",
".json[1][3][0][1]"
]