Reputation:
I'm trying to find out how to use jq to remove a certain value that occurs anywhere in the schema in an array.
In this case i'm trying to remove agent4 from anywhere inside an array underneath the field labelled agents.
This is what I have so far
jq '..|.agents? | select(. != null) | map(select(. != "agent4"))'
But that just creates the changed data and I don't know how to re-assign it to the path.
I originally tried using sed for this but its definitely not the tool to use so I switched to jq.
{
"environments": {
"default": {
"machines": {
"dev-machine": {
"agents": [
"agent1",
"agent2",
"agent3",
"agent4"
]
}
}
}
},
"environments2": {
"agents": [
"agent1",
"agent2",
"agent3",
"agent4"
]
}
}
However this just outputs
[
"agent1",
"agent2",
"agent3"
]
[
"agent1",
"agent2",
"agent3"
]
Upvotes: 4
Views: 1226
Reputation: 14695
Here is a solution which uses path to find "agent4" and verify it appears within "agents" before removing it with delpaths
delpaths([ path(..|select(.=="agent4")) | select(.[-2]=="agents") ])
Sample Run (assumes data in data.json
)
$ jq -M 'delpaths([ path(..|select(.=="agent4")) | select(.[-2]=="agents") ])' data.json
{
"environments": {
"default": {
"machines": {
"dev-machine": {
"agents": [
"agent1",
"agent2",
"agent3"
]
}
}
}
},
"environments2": {
"agents": [
"agent1",
"agent2",
"agent3"
]
}
}
Here is another way using reduce, leaf_paths, getpath and delpaths:
reduce leaf_paths as $p (.;
if $p[-2]=="agents" and getpath($p)=="agent4" then delpaths([$p]) else . end
)
Upvotes: 0
Reputation: 116900
Here's a solution using walk
:
walk( if type == "object" and has("agents")
then .agents |= map(select(. != "agent4"))
else . end )
If you want to remove the value from all arrays, wherever they occur:
walk( if type == "array" then map(select(. != "agent4")) else . end )
If you want a more flexible solution, you could, for example, replace "agent4"
by $value
, and then set $value
on the command-line, e.g. using --arg value VALUE
if VALUE is a string, or --argjson value VALUE
as appropriate.
If your jq does not have walk
, simply prepend its definition, which is available (for example) from https://github.com/stedolan/jq/blob/master/src/builtin.jq
Upvotes: 2