说我有这样的JSON:
{
"json": [
"a",
[
"b",
"c",
[
"d",
"foo",
1
],
[
[
42,
"foo"
]
]
]
]
}
Run Code Online (Sandbox Code Playgroud)
我想要一个jq包含foo以下内容的索引路径数组:
[
".json[1][2][1]",
".json[1][3][0][1]"
]
Run Code Online (Sandbox Code Playgroud)
我可以使用jq以及如何实现此目的吗?我试图recurse | .foo先获得比赛,但收到错误:Cannot index array with string "foo".
小智 8
首先,我不确定获得一系列jq程序的目的是什么.虽然存在这样做的手段,但它们很少是必要的; jq不提供任何类型的eval命令.
jq具有路径的概念,路径是一个字符串和数字的数组,表示JSON中元素的位置; 这相当于预期输出的字符串.作为一个例子,".json[1][2][1]"将表示为["json", 1, 2, 1].标准库包含了这个概念操作多种功能,如getpath,setpath,paths和leaf_paths.
因此,我们可以获取给定JSON中的所有叶子路径并迭代它们,选择它们在输入JSON中的值为"foo"的那些,并从中生成一个数组:
jq '[paths as $path | select(getpath($path) == "foo") | $path]'
Run Code Online (Sandbox Code Playgroud)
对于您的给定输入,这将返回以下输出:
[
["json", 1, 2, 1],
["json", 1, 3, 0, 1]
]
Run Code Online (Sandbox Code Playgroud)
现在,虽然它不应该是必要的,并且很可能表明您正在以错误的方式处理您遇到的任何问题,但是可以通过转换每条路径将这些数组转换为您寻找的jq路径字符串以下脚本:
".\(map("[\(tojson)]") | join(""))"
Run Code Online (Sandbox Code Playgroud)
因此,完整的脚本将是:
jq '[paths as $path | select(getpath($path) == "foo") | $path | ".\(map("[\(tojson)]") | join(""))"]'
Run Code Online (Sandbox Code Playgroud)
它的输出将是:
[
".[\"json\"][1][2][1]",
".[\"json\"][1][3][0][1]"
]
Run Code Online (Sandbox Code Playgroud)