1

I need a jq command to replace array values with non-json standard values i.e. in the following json input I need to replace the "webOrigins" array values with a non-json value, which is a Jinja2 template variable replacement as per the second json block below.

Input (example.json)

{
   "clients": [
     {
        "clientId": "abc",
        "webOrigins": [ "/", "/api" ]
     },
     {
        "clientId": "xyz",
        "webOrigins": [ ]
     }
   ]
}

Desired Output

{
   "clients": [
     {
        "clientId": "abc",
        "webOrigins": {{clients.abc.webOrigins}}
     },
     {
        "clientId": "xyz",
        "webOrigins": {{clients.xyz.webOrigins}}
     }
   ]
}

My current attempt of shell script calling jq to loop through the input json and replace with template variable is this

for clientId in $(jq -r '.clients[] | .clientId' example.json)
do
  jq '(.clients[] | select(.clientId == "'${clientId}'") | .webOrigins) |= {{ clients['\'${clientId}\''].webOrigins | default([]) }}' example.json > tmp.j2; mv -f tmp.j2 example.json
done

But fails with the error:

jq: error: syntax error, unexpected '{' (Unix shell quoting issues?) at <top-level>, line 1:
(.clients[] | select(.clientId == "abc") | .webOrigins) |= {{ clients['abc'].webOrigins | default([]) }}                                                            
jq: 1 compile error

Of course if I add double quotes around the template variable to make the replacement variable valid json the script works but I need the value to not have quotes.

1
  • 2
    Would sth like jq '.clients[].webOrigins = ""' file | sed 's/""/{{clients.abc.webOrigins}}/g' do? Commented Mar 13, 2020 at 10:29

1 Answer 1

2

It would be impractical to implement a jq-only solution, but jq can certainly help, e.g. the following works in your case:

jq '.clients[] |= (.webOrigins = "{{clients.\(.clientId).webOrigins}}")' |
    sed '/"webOrigins":/ { s/"[{][{]/{{/; s/[}][}]"$/}}/; }'
Sign up to request clarification or add additional context in comments.

2 Comments

I think you can omit the [...] around each brace in the regular expressions; sed can tell by context that they aren't part of a bound.
i ended up going with something like that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.