I'd like to return a simplified, filtered yaml document based on some nested keys. I haven't yet found how to accomplish this, but given how powerful mikefarah/yq is, I'm confident it is doable.
Given input:
ns-a:
name-a:
-
prop-a: "aye"
prob-b:
stuff: "that doesn't matter"
target-prop: "just-me"
-
prop-a: "aye"
target-prop: "not-me"
name-b:
-
prop-a: "aye"
target-prop: "just-me"
-
prop-a: "aye"
prob-b:
stuff: "that doesn't matter"
target-prop: "not-me"
ns-b:
name-a:
-
prop-a: "aye"
target-prop: "just-me"
-
prop-a: "aye"
prob-b:
stuff: "that doesn't matter"
target-prop: "not-me"
name-b:
-
prop-a: "aye"
target-prop: "just-me"
-
prop-a: "aye"
prob-b:
stuff: "that doesn't matter"
target-prop: "not-me"
I would like to return:
ns-a:
name-a:
-
target-prop: "just-me"
name-b:
-
target-prop: "just-me"
ns-b:
name-a:
-
target-prop: "just-me"
name-b:
-
target-prop: "just-me"
Where the structure remains intact, but only the target-prop
is exposed and only when it is "just-me".
I can sort of accomplish this with ripgrep, but this is not the ideal way to deal with structured data.
rg -N '^\w|^ \w|target-prop: "just-me"' tmp.yaml
Yields:
ns-a:
name-a:
target-prop: "just-me"
name-b:
target-prop: "just-me"
ns-b:
name-a:
target-prop: "just-me"
name-b:
target-prop: "just-me"
Close, but no cigar.
You could update |=
at the second level .[][]
by reducing the array items to objects only containing the desired key using pick
, then select
those that match in content, and take the first using .[0]
(structurally, there could be more than just one, as in your sample):
yq '.[][] |= (map(pick(["target-prop"]) | select(.[] == "just-me")) | .[0])'
ns-a:
name-a:
target-prop: "just-me"
name-b:
target-prop: "just-me"
ns-b:
name-a:
target-prop: "just-me"
name-b:
target-prop: "just-me"
Tested with mikefarah/yq v4.34.2