I need to write a command via jq which is:
- compares old and new config json files (old-o-ru.conf and new-o-ru.conf).
- Copies the value of the element from the old config to the new one, if the new one has this element and their types match.
- Unaffected elements in the new config should remain.
old.conf:
{
    "ru_conf": {
        "network": {
            "interface": "eth1",
            "mac_address": "FF:FF:FF:FF:FF:FF",
            "setup": true,
            "interfaceы": ["eth0", "eth1"],
            "numbers": [1, 2, 3],
            "float": 1111.1111,
            "partitions": [
                {
                  "dev1": "/mnt/data/",
                  "threshold": 20,
                }
            ]
        }
    }
}
new.conf:
{
    "ru_conf": {
        "network": {
            "interface": "str",
            "mac_address": "str",
            "setup": false,
            "interfaceы": ["str1", "str2"],
            "numbers": [0, 0, 0],
            "int": 0,
            "partitions": [
                {
                  "dev1": "str",
                  "threshold": 0,
                }
            ]
        }
    }
}
Differences in configs: there is no "int" field in old.conf there is no "float" field in new.conf
I am using the command:
jq -s '.[1].ru_conf as $new | .[0] | .ru_conf |= reduce paths(scalars) as $p (.; if ($new | getpath($p)) and (getpath($p) | type) == ($new | getpath($p) | type) then setpath($p; $new | getpath($p)) else . end)' ./new.conf ./old.conf > merged-config.conf
Result:
{
  "ru_conf": {
    "network": {
      "interface": "eth1",
      "mac_address": "FF:FF:FF:FF:FF:FF",
      "setup": false,
      "interfaces": [
        "eth0",
        "eth1"
      ],
      "numbers": [
        1,
        2,
        3
      ],
      "int": 0,
      "partitions": [
        {
          "dev1": "/mnt/data/",
          "threshold": 20
        }
      ]
    }
  }
}
Expected output:
{
    "ru_conf": {
        "network": {
            "interface": "str",
            "mac_address": "str",
            "setup": true,
            "interfaces": ["str1", "str2"],
            "numbers": [0, 0, 0],
            "int": 0,
            "partitions": [
                {
                  "dev1": "str",
                  "threshold": 0
                }
            ]
        }
    }
}
Differences from result and expected result: "setup": false
Also tried this:
jq \
 --argjson a "$(cat ./new.conf)" \
 --argjson b "$(cat ./old.conf)" \
 -n '
   $a | .ru_conf | keys_unsorted as $whitelist 
 | $b | .ru_conf | with_entries( select(.key | IN($whitelist[])) ) as $update
 | $a | .ru_conf += $update '
Result:
{
  "ru_conf": {
    "network": {
      "interface": "eth1",
      "mac_address": "FF:FF:FF:FF:FF:FF",
      "setup": true,
      "interfaces": [
        "eth0",
        "eth1"
      ],
      "numbers": [
        1,
        2,
        3
      ],
      "float": 1111.1111,
      "partitions": [
        {
          "dev1": "/mnt/data/",
          "threshold": 20
        }
      ]
    }
  }
}
But the second command does not support type comparison and nesting
How can I achieve the required result?
 
    