jsonyq

yq expression to replace first-level keys with their values?


Given input JSON like this:

{
    "a": {
        "aa": {
            "aaa1": "value",
            "aaa2": "value"
        }
    },
    "b": {
        "bb": {
            "bbb1": "value",
            "bbb2": "value"
        }
    }
}

I want to use Mike Farah's yq to replace first-level keys with their values, and output:

aa:
  aaa1: value
  aaa2: value
bb:
  bbb1: value
  bbb2: value

Notes:

That is, I want to replace each first-level key with its (one and only) child.

I've spent hours trying to do this with various operators. I'm stumped.

For example, I thought perhaps I could simply iterate over the first-level keys and replace them with their values:

with_entries(.parent |= .value)

or (very similar, just clutching at straws):

with_entries(.parent |= .)

Nope. Neither seems to have any effect. (Their output is the same as their input.)

I'd prefer to not embarrass myself further by describing my other failed attempts.


Solution

  • Note that your JSON input, formatted as YAML, already looks like this:

    a:
      aa:
        aaa1: value
        aaa2: value
    b:
      bb:
        'bbb1:': value
        'bbb2:': value
    

    Thus, to get a document containing just the second-level content (regardless of the number of the keys contained, btw), simply iterate over the first level using .[], and set the output format to YAML using --output-format yaml or -oy (if needed, depending on the extension of your input file, also set the input format to JSON using --input-format json or -pj):

    yq -pj -oy '.[]' input.json 
    
    aa:
      aaa1: value
      aaa2: value
    bb:
      'bbb1:': value
      'bbb2:': value
    

    Note that your JSON input sample has colons in the keys bbb1: and bbb2: (maybe just a typo), so they get escaped (quoted) in the output YAML.