The goal is to delete an entire object in a JSON file that contain a key/value pair specified in a JQ script.
For example, all objects with /unwanted-path/
in path
would be removed:
input.json:
[
{
"path": "/path-1/",
"guide": "Guide 1"
},
{
"path": "/path-2/",
"guide": "Guide 2"
},
{
"path": "/unwanted-path/",
"guide": "Guide 3"
}
]
output.json:
[
{
"path": "/path-1/",
"guide": "Guide 1"
},
{
"path": "/path-2/",
"guide": "Guide 2"
}
]
This JQ script is the closest I have come to in terms of a potential successful approach, but of course its intent is different and does not accomplish the goal.
jq '.[] | walk(if type == "object" then del(.path) else . end)' original.json > modified.json
Is there a way to add logic there that designates a key to go with path
?
The key will always be path
, but there are several path
values I will filter against. If there is a way to filter against more than one path
value a time, that is ideal, but not critical.
The following code shows how to solve your task with four examples
#!/bin/bash
FILE='
[
{
"path": "/path-1/",
"guide": "Guide 1"
},
{
"path": "/unwanted-path-2/",
"guide": "Guide 2"
},
{
"path": "/path-3/",
"guide": "Guide 3",
"sub": [
{
"path": "/unwanted-path-4/",
"guide": "Guide 4"
},
{
"path": "/path-5/",
"guide": "Guide 5"
},
[
{
"path": "/path-6/",
"guide": "Guide 6"
},
{
"path": "/unwanted-path-7/",
"guide": "Guide 7"
}
]
]
}
]
'
UNWANTED='/unwanted-path-2/'
echo "example 1: keep only objects in array that does not have the unwanted path '$UNWANTED' (narrow search)"
jq --arg unwantedPath "$UNWANTED" \
'map(select(.path != $unwantedPath))' <<< "$FILE"
UNWANTED='/unwanted-path-7/'
echo -e "\nexample 2: delete objects that have the unwanted path '$UNWANTED' exactly (deep search)"
jq --arg unwantedPath "$UNWANTED" \
'del(..| objects | select(.path == $unwantedPath)) ' <<< "$FILE"
UNWANTED='unwanted'
echo -e "\nexample 3: delete objects that have the unwanted path '$UNWANTED' partially (deep search)"
jq --arg unwantedPath "$UNWANTED" \
'del(..| objects | select(.path | index($unwantedPath) != null)) ' <<< "$FILE"
UNWANTED='["/unwanted-path-4/", "/unwanted-path-7/"]'
echo -e "\nexample 4: delete objects that have one of unwanted paths '$UNWANTED' (deep search)"
jq --argjson unwantedPath "$UNWANTED" \
'del(..| objects | select(.path | IN($unwantedPath[]))) ' <<< "$FILE"
[
{
"path": "/path-1/",
"guide": "Guide 1"
},
{
"path": "/path-3/",
"guide": "Guide 3",
"sub": [
{
"path": "/unwanted-path-4/",
"guide": "Guide 4"
},
{
"path": "/path-5/",
"guide": "Guide 5"
},
[
{
"path": "/path-6/",
"guide": "Guide 6"
},
{
"path": "/unwanted-path-7/",
"guide": "Guide 7"
}
]
]
}
]
[
{
"path": "/path-1/",
"guide": "Guide 1"
},
{
"path": "/unwanted-path-2/",
"guide": "Guide 2"
},
{
"path": "/path-3/",
"guide": "Guide 3",
"sub": [
{
"path": "/unwanted-path-4/",
"guide": "Guide 4"
},
{
"path": "/path-5/",
"guide": "Guide 5"
},
[
{
"path": "/path-6/",
"guide": "Guide 6"
}
]
]
}
]
[
{
"path": "/path-1/",
"guide": "Guide 1"
},
{
"path": "/path-3/",
"guide": "Guide 3",
"sub": [
{
"path": "/path-5/",
"guide": "Guide 5"
},
[
{
"path": "/path-6/",
"guide": "Guide 6"
}
]
]
}
]
[
{
"path": "/path-1/",
"guide": "Guide 1"
},
{
"path": "/unwanted-path-2/",
"guide": "Guide 2"
},
{
"path": "/path-3/",
"guide": "Guide 3",
"sub": [
{
"path": "/path-5/",
"guide": "Guide 5"
},
[
{
"path": "/path-6/",
"guide": "Guide 6"
}
]
]
}
]