6

I have got a configuration with content to be exchanged with snippets from separate file. How would I neatly achieve this?

Config file might look like:

# config file
{
    "keep": "whatever type of value",
    "manipulate": [
        {
            "foo": "bar",
            "cat": {
                "color": "grey"
            },
            "type": "keep",
            "detail": "keep whole array element"
        },
        {
            "stuff": "obsolete",
            "more_stuff": "obsolete",
            "type": "replace",
            "detail": "replace whole array element with content from separate file"
        },
        {
            "foz": "baz",
            "dog": {
                "color": "brown"
            },
            "type": "keep",
            "detail": "keep whole array element"
        },

    ],
    "also_keep": "whatever type of value"
}

The content (coming from separate file) to be inserted as a replacement of obsolete array element:

# replacement
{
    "stuff": "i want that",
    "fancy": "very",
    "type": "new"
}

The desired result should look like:

# result
{
    "keep": "whatever kind of value",
    "manipulate": [
        {
            "foo": "bar",
            "cat": {
                "color": "grey"
            },
            "type": "keep",
            "detail": "keep whole array element"
        },
        {
            "stuff": "i want that",
            "fancy": "very",
            "type": "new"
        },
        {
            "foz": "baz",
            "dog": {
                "color": "brown"
            },
            "type": "keep",
            "detail": "keep whole array element"
        },

    ],
    "also_keep": "whatever kind of value",
}

Requirements:

  • Content replacement needs to be done based on type key's value.
  • Preferably use jq and common bash/linux tools.
  • Array element ordering should stay same
peak
  • 105,803
  • 17
  • 152
  • 177
ITL
  • 422
  • 1
  • 5
  • 17
  • You need to explain how this replacement works, because it's not obvious for me how you got "result" from "config file". It's not simple replacement. – Stalinko Sep 14 '17 at 10:16
  • @Stalinko You maybe missed the 2nd section _# replacement_? And, yes, the question is, how to get (_# result_) from original input (_# configfile_) by using snippet _# replacement_ – ITL Sep 14 '17 at 10:19

2 Answers2

4

jq solution:

jq --slurpfile repl repl.json '.manipulate=[.manipulate[] 
     | if .type=="replace" then .=$repl[0] else . end]' config.json
  • repl.json - json file containing replacement JSON data

  • --slurpfile repl repl.json - reads all the JSON texts in the named file and binds an array of the parsed JSON values to the given global variable

The output:

{
  "keep": "whatever type of value",
  "manipulate": [
    {
      "foo": "bar",
      "cat": {
        "color": "grey"
      },
      "type": "keep",
      "detail": "keep whole array element"
    },
    {
      "stuff": "i want that",
      "fancy": "very",
      "type": "new"
    },
    {
      "foz": "baz",
      "dog": {
        "color": "brown"
      },
      "type": "keep",
      "detail": "keep whole array element"
    }
  ],
  "also_keep": "whatever type of value"
}
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
3
jq --slurpfile repl repl.json '.manipulate |= 
  map(if .type=="replace" then $repl[0] else . end)' config.json
peak
  • 105,803
  • 17
  • 152
  • 177