Yq: Any way to list top level keys only?

Created on 23 Aug 2017  路  9Comments  路  Source: mikefarah/yq

Is it currently possible to have the CLI only list the top level keys? For example, given the following yaml file:

a:
  b:
    c:
    - 'test'
    - "test2"
  d:
  e:

Is there a way to only list b, d and e and no other subkeys with something like yaml r test.yml a?

enhancement yaml-v3

Most helpful comment

Workaround staying with sed only solution, based on the fact that yq trim keys on left:

GNU sed:

  • -n no print
  • /^\([^ ]\([^:]\+\)\?\):/ match left anchored keys: non-space, followed optionally by non-colon
  • s/:.*/ remove colon plus end of the line
  • p print (behave like grep filtering)
yaml_keys () 
{ 
    yq r "$1" "$2" | sed -n -e '/^\([^ ]\([^:]\+\)\?\):/  s/:.*// p'
}

Use with the same previous comment input:

yaml_keys a.yml f

outputs

key2

All 9 comments

Not at the moment sorry - happy to take a pull request for this.

Alternatively, you could pipe it out to json (-j), use jq then convert it back to yaml (yaml will take a json file and output yaml)

Thanks, I might take a stab at it.

You could also pipe the output into a grep -v to get rid of they subkeys you don't want to see. For example, test and test1 will both have multiple spaces before them in the output, so if you pipe yaml's output into a grep -v ' .*', this will output everything that does not start with two spaces.

Ex:

yaml r ./yamltest a
b:
  c:
  - test
  - test2
d: null
e: null
yaml r ./yamltest a | grep -v '  .*'
b:
d: null
e: null

i had to do this to remove the : at last.
yq r test.yml my_key | grep -v ' .*' | sed 's/.$//'

Expanding on @sumanthkumarc's one-liner:

yq r test.yml my_key | grep -v '^ .*' | sed 's/:.*$//'

This deals with several edge-cases, such as:

  • when the key's tree is empty;
  • there are spaces in the key name.

What would be the yq syntax for extracting keys?

Like in jq?

yq r file.yml 'path.to.top_key|keys[]'

Suggestion from @mikefarah to use jq for that:

give this input

---
a:
b:
  c:
    - test
    - test2
d:
e:
f:
  key1: value1
  key2: value

filtering

yq.v2 r -j a.yml | jq '.f|keys[]'

Alternative filtering from yaml (jq like root key naming .f is not supported by yq)

yq.v2 r -j a.yml f | jq '.|keys[]'

both outputs:

"key1"
"key2"

add -r to jq for bash compatible extraction.

yq.v2 r -j a.yml f | jq -r '.|keys[]'

Workaround staying with sed only solution, based on the fact that yq trim keys on left:

GNU sed:

  • -n no print
  • /^\([^ ]\([^:]\+\)\?\):/ match left anchored keys: non-space, followed optionally by non-colon
  • s/:.*/ remove colon plus end of the line
  • p print (behave like grep filtering)
yaml_keys () 
{ 
    yq r "$1" "$2" | sed -n -e '/^\([^ ]\([^:]\+\)\?\):/  s/:.*// p'
}

Use with the same previous comment input:

yaml_keys a.yml f

outputs

key2

Just released a new version of yaml that fixes this - it's a pretty significant update so it's still in beta: https://github.com/mikefarah/yq/releases/tag/3.0.0-beta

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tamalsaha picture tamalsaha  路  5Comments

nicholasdille picture nicholasdille  路  7Comments

mkyc picture mkyc  路  6Comments

ykfq picture ykfq  路  8Comments

cdaguerre picture cdaguerre  路  4Comments