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?