GGGforce
GGGforce

Reputation: 653

JQ: perform token replacement

I'd like to replace the tokens in text with the variables defined in ma. Input JSON:

{
    "ma":{
        "a":"1",
        "b":"2",
        "c":"3"
    },
    "mb":{
        "a":"11"
    },
    "text":"https://ph.com?a={a}&b={b}"
}

Desired result: https://ph.com?a=1&b=2

Extra credit, how can I have mb variables take precedence over ma variables so that my resulting text is: https://ph.com?a=11&b=2 ?

I've tried using combinations of scan and sub and walk but can't figure it out.

Thanks!

Upvotes: 1

Views: 584

Answers (2)

peak
peak

Reputation: 116690

If you're stuck with the {a}-style template names, then see @JeffMercado's answer; if, however, you have control over the templating style, it would make things much simpler if you used jq's string-interpolation feature.

For example, if the template string (.text) were "https://ph.com?a=\\(.a)&b=\\(.b)" then if you just want the value of .text after substitution, you could simply write:

(.ma + .mb) as $map | .text | $map

Or if you wanted in-place substitution:

(.ma + .mb) as $map
| .text |= $map

Upvotes: 1

Jeff Mercado
Jeff Mercado

Reputation: 134811

Define a function to replace the tokens with the new values.

def format($map): gsub("\\{(?<key>[^}]+)\\}"; "\($map[.key])");

With this, you can then pass in the map for the replacements.

.ma as $map | .text | format($map)

Update the mapping as needed.

(.ma * .mb) as $map | .text | format($map)

Upvotes: 2

Related Questions