skip to Main Content

Suppose I have a JSON file like this:

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

This is my JSON model.

Then I have a text file like this:

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

This is my template. Curly braces can be replaced with anything else, if it makes the rendering easier.

When that template is rendered against the aforementioned JSON model we should get this:

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

Does jq allow us to perform such a rendering?

Right now I use envsubst to do this kind of things (the template looks differently, of course), but it is too messy.

2

Answers


  1. Let’s assume input.json contains your json input, and template.txt contains

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

    (Notice I changed slightly the third jq expression to make it an array.)

    Following perl script produeces expected ouput.

    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
    

    Output:

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

    You may need to adapt above script if your template becomes more complex.

    Also be aware that above script extracts jq script from template, so you need to have total control of the template to avoid code injection issue.

    Login or Signup to reply.
  2. Here’s a jq-only solution to the stated problem.

    With your text input and $json set to the given JSON:

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

    produces:

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

    For a bit more generality, you’d want to add more gsub filters.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search