4

I have a templatized json file called template.json as below:

{
  "subject": "Some subject line",
  "content": $CONTENT,
}

I have another file called sample.json with the json content as below:

{
"status": "ACTIVE",
"id": 217,
"type": "TEXT",
"name": "string",
"subject": "string",
"url": "contenttemplates/217",
"content": {
    "text": "hello ${user_name}",
    "variables": [{
        "key": "${user_name}",
        "value": null
    }]
},
"content_footer": null,
"audit": {
    "creator": "1000",
    "timestamp": 1548613800000,
    "product": "2",
    "channel": "10",
    "party": null,
    "event": {
        "type": null,
        "type_id": "0",
        "txn_id": "0"
    },
    "client_key": "pk6781gsfr5"
}

}

I want to replace $CONTENT from template.json with the content under the tag "content" from the content.json file . I have tried with below sed commands:

sed -i 's/$CONTENT/'$(jq -c '.content' sample.json)'/' template.json

I am getting below error:

sed: -e expression #1, char 15: unterminated `s' command

Can someone please help me to get the right sed command (or any other alternative)?

peak
  • 105,803
  • 17
  • 152
  • 177
Ajinkya Bambal
  • 101
  • 2
  • 8

3 Answers3

4

The jq Cookbook has a section on using jq with templates: https://github.com/stedolan/jq/wiki/Cookbook#using-jq-as-a-template-engine

In the present case, the first technique ("Using jq variables as template variables") matches the already-defined template file (except for the dangling comma), so you could for example write:

jq -n --arg CONTENT "$(jq -c .content sample.json)" '
  {"subject": "Some subject line", "content": $CONTENT}'

or use the format:

jq -n --arg CONTENT "$(jq -c .content sample.json)" -f template.jq

(I'd only use the .json suffix for files that hold JSON or JSON streams.)

peak
  • 105,803
  • 17
  • 152
  • 177
  • Not so bad trick to treat the template as a jq file rather than json. But I wouldn't really recommend that because that means you are bound to `jq` from that moment on. Making the template valid json sounds like a better, portable approach for me. – hek2mgl Jan 28 '19 at 18:11
  • @hek2mgl - That's why I mentioned the jq Cookbook section, which documents two other techniques. – peak Jan 28 '19 at 18:51
0

The output from jq contains spaces, you need to quote them to prevent the shell from tokenizing them.

sed -i 's/$CONTENT/'"$(jq -c '.content' sample.json)/" template.json

See further When to wrap quotes around a shell variable?

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • What if content contains `\1` or an `&`? :P – hek2mgl Jan 28 '19 at 14:13
  • 1
    Then you have more problems. I don't particularly recommend `sed` for this, to be sure. – tripleee Jan 28 '19 at 14:19
  • 1
    I don't want to be pedantic, but probably you can just say that. Imo the OP using a json template which is not valid json is a very bad idea to start with and the source of this problem. If the template would use `"content": "$content"` (for example), this would be much less of a problem because `jq` could be used to render the template – hek2mgl Jan 28 '19 at 14:21
0

With GNU sed:

sed '/$CONTENT/{s/.*/jq -c ".content" sample.json/e}'

Replace the entire line with your command and e (GNU only) to execute the command and replace sed's pattern space with the output of the command.

stevesliva
  • 5,351
  • 1
  • 16
  • 39