remove keys that are present in sibling object and have a certain value

Viewed 200

I have the following input file:

{
    "dic": {
        "a": "",
        "b": "",
        "c": "",
        "d": ""
    },
    "remove": {
        "b": true,
        "c": false,
        "d": true
    }
}

I want to remove with jq all elements of the dictionary dic which are also in the dictionary remove with the value true.

This would be the output:

{
    "dic": {
        "a": "",
        "c": ""
    },
    "remove": {
        "b": true,
        "c": false,
        "d": true
    }
}

I am not sure how to do this. I would first need to clean the remove dic and only get the keys with the value true. Then I would need to somehow only delete these keys from dic.

3 Answers

You don't need anything other than JQ for that.

[.remove | path(.[] | select(.))] as $p | .dic |= delpaths($p)

Online demo

If there might be other values in remove than true and false, use

select(. == true)

instead of

select(.)

Here's a straightforward and efficient solution using jq alone:

(.remove | with_entries(select(.value == true))) as $remove
| .dic |= with_entries(select($remove[.key] | not))

That can be done using bash loops:

#!/bin/bash
# saving the json so we can manipulate it freely
data="$(cat data.json)"
for k in $(echo "$data" | jq '.remove' | jq -r keys[]) # getting all the keys from remove
do
    # skipping the key if it isn't supposed to be removed
    [ $(echo "$data" | jq .remove.$k) == 'false' ] && continue
    data="$(echo "$data" | jq "del(.dic.$k)")" # removing the key
done
echo "$data" # final json without the keys
Related