Reputation: 1750
When given a string in JSON where I'd like only a part of it templated/substituted:
{
"title": "Where the $color Fern Grows"
}
Trying to template that with jq
args doesn't seem to work:
cat example.json | jq --arg color "Red"
jq
doesn't like the substitution and returns the un-templated example.json with $color
in the output
How can you tell jq
to replace variables mid JSON string?
Thanks.
The issue seems to be that jq
assumes data on stdin is formatted JSON data. This substitution actually only works on a "filter", which is jq
's term for a script. Using the flags -n
and -f [filter.json]
to correctly state the input data is a filter, not actual data and using the \($var)
syntax, as @peak pointed out works well.
example.json
then could become example.jq
:
{
"title": "Where the \($color) Fern Grows"
}
Which when run, as they suggested:
jq -n --arg color "Red" -f example.jq
Works perfectly. The concept between data and filter is important and one I didn't realize. I thought it was all just interpolation and templating like most other programs. This seems to take more inspiration from awk
where this is common however.
Upvotes: 1
Views: 2917
Reputation: 116870
For suggested ways to use jq as a template engine, see the jq Cookbook: https://github.com/stedolan/jq/wiki/Cookbook#using-jq-as-a-template-engine
In your case, it would probably be better to use the "interpolation" approach as per your original SO question: jq not replacing json value with parameter
{
"title": "Where the \($color) Fern Grows"
}
jq -n --arg color Red -f example.jq
or:
jq --arg color Red . <(example.jq)
... you could use sub
, though that might be brittle.
Upvotes: 3