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
2
  • 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. Commented Sep 14, 2017 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 Commented Sep 14, 2017 at 10:19

2 Answers 2

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"
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thx, you made my day.. Works perfectly
3
jq --slurpfile repl repl.json '.manipulate |= 
  map(if .type=="replace" then $repl[0] else . end)' config.json

Comments

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.