I have a big YAMl file and i need to select all top mapping keys, that have other mapping key under them. It would be great if i could done parsing with yq, but other solutions are welcome too For example, i have yaml file
foo:
bar:
- "hello"
quz:
bar:
- "hi"
der:
boo: true
and i need to select just foo and bar so my final yaml will look like this:
foo:
bar:
- "hello"
quz:
bar:
- "hi"
I already tried something like this, it is do nothing test.yaml contains example above
yq eval 'select(.[] | has("bar"))' test.yml
yq eval 'select(.[] | .bar != null)' test.yml
And i generally do not understand why using query without select gives me correct boolean output
yq eval '.[] | has("bar")' test.yml
true
true
false
With
.[] | has("bar")you get the booleans you would use in a wrappingselectexpression, but you're missing that.[]destructures the outer map (to generate the booleans) whileselectis still applied to the whole map (as it's in the outer context).One way to achieve what you want is using
with_entries, which takes a function that is provided access to each.keyand.value, but retains the outer structure:Another way could be to use the
pickfunction, which takes a list of keys to keep. Generate that list by applying your original filter, and extracting eachkeyfrom the matches (while usingmapinstead of.[]to retain the array):Both output:
Tested with mikefarah/yq version v4.35.1. Note that since version v4.18.1, the
eval/ecommand is the default, and can be omitted. (As an aside, thewith_entriesapproach should also work as is using kislyuk/yq.)