如何使用jq(和其他一些实用程序)在bash中使用JSON模型实现一个简单的模板渲染器?

1cosmwyk  于 2023-05-02  发布在  其他
关注(0)|答案(2)|浏览(106)

假设我有一个这样的JSON文件:

{
  "a": 1,
  "b": [1, 2],
  "c": [{
    "x": 1
  }, {
    "x": 2
  }]
}

这是我的JSON模型。
然后我有一个这样的文本文件:

A is {.a} and B is an array {.b}.
There is also c[].x = {.c[].x}

这是我的模板。如果使渲染更容易,可以使用任何其他内容替换花括号。
当模板针对上述JSON模型呈现时,我们应该得到以下内容:

A is 1 and B is an array [1,2].
There is also c[].x = [1,2]

jq允许我们执行这样的渲染吗?
现在我使用envsubst来做这类事情(当然,模板看起来不同),但它太乱了。

cngwdvgl

cngwdvgl1#

这里有一个针对上述问题的仅jq解决方案。
将文本输入和$json设置为给定的JSON:

jq -nrR --argjson json "$json" 'inputs
  | gsub("\\{.(?<v>[^[}]+)\\}"; $json[.v]|tostring) 
  | gsub("\\{.(?<v>[^[}]+)\\[][.](?<x>[^}]+)\\}"; [$json[.v][][.x]]|tostring ) 
'

生产:

A is 1 and B is an array [1,2].
There is also c[].x = [1,2]

为了更一般化一点,您需要添加更多的gsub过滤器。

uttx8gqw

uttx8gqw2#

假设input.json包含json输入和模板。txt包含

A is {.a} and B is an array {.b}.
There is also c[].x = {[.c[].x]}

(注意我稍微修改了第三个jq表达式,使其成为一个数组。)
以下perl脚本produeces预期输出。

perl -pe '
sub procjq {
    $in = shift;
    $output = qx[jq -c "$in" input.json];
    chop($output);
    return $output;
}
s/(\{.*?\})/procjq(substr($1,1,-1))/eg
' template.txt

输出:

A is 1 and B is an array [1,2].
There is also c[].x = [1,2]

如果你的模板变得更复杂,你可能需要修改上面的脚本。
还要注意的是,上面的脚本从模板中提取了jq脚本,因此您需要完全控制模板以避免代码注入问题。

相关问题