How to convert a json response into yaml in bash How to convert a json response into yaml in bash json json

How to convert a json response into yaml in bash


yq a yaml wrapper for jq

With yq version 4.8.0:

cat $DEFAULTS_FILE | yq e -P -

  • e or eval handles file separately. ea or eval-all will merge files first.
  • -P or --prettyPrint YAML output
  • - from STDIN

Note: you can go the other way (yaml to json) too yq e -j file.yaml

With yq version 3.3.2:

cat $DEFAULTS_FILE | yq r -P -

  • r read
  • -P --prettyPrint
  • - from STDIN


function yaml_validate {  python -c 'import sys, yaml, json; yaml.safe_load(sys.stdin.read())'}function yaml2json {  python -c 'import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin.read())))'}function yaml2json_pretty {  python -c 'import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin.read()), indent=2, sort_keys=False))'}function json_validate {  python -c 'import sys, yaml, json; json.loads(sys.stdin.read())'}function json2yaml {  python -c 'import sys, yaml, json; print(yaml.dump(json.loads(sys.stdin.read())))'}

More Bash tricks at http://github.com/frgomes/bash-scripts


I'm not sure what rules you're using to get to your expected result. It seems like you're randomly applying different rules to how the values are being converted.

As I understand it, scalar values are just output as is (with potential encoding), objects are output as key/value pairs, and array objects are output with a - for every item. The indentation associates what's part of what.

So based on those rules if you're going to use jq:

def yamlify:    (objects | to_entries[] | (.value | type) as $type |        if $type == "array" then            "\(.key):", (.value | yamlify)        elif $type == "object" then            "\(.key):", "    \(.value | yamlify)"        else            "\(.key):\t\(.value)"        end    )    // (arrays | select(length > 0)[] | [yamlify] |        "  - \(.[0])", "    \(.[1:][])"    )    // .    ;

Then to use it, add it to your .jq file and use it:

$ jq -r yamlify input.jsonusers:  - name:       pi    gecos:      Hypriot Pirate    sudo:       ALL=(ALL) NOPASSWD:ALL    shell:      /bin/bash    groups:     users,docker,video    plain_text_passwd:  pi    lock_passwd:        false    ssh_pwauth: true    chpasswd:        expire: false  - name:       admin    gecos:      Hypriot Pirate    sudo:       ALL=(ALL) NOPASSWD:ALL    shell:      /bin/bash    primary-group:      users    groups:     users,docker,adm,dialout,audio,plugdev,netdev,video    ssh-import-id:      None    plain_text_passwd:  pi    lock_passwd:        true    ssh_pwauth: true    chpasswd:   {expire: false}    ssh-authorized-keys:      - ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local

Here's another variation that aligns the values

def yamlify2:    (objects | to_entries | (map(.key | length) | max + 2) as $w |        .[] | (.value | type) as $type |        if $type == "array" then            "\(.key):", (.value | yamlify2)        elif $type == "object" then            "\(.key):", "    \(.value | yamlify2)"        else            "\(.key):\(" " * (.key | $w - length))\(.value)"        end    )    // (arrays | select(length > 0)[] | [yamlify2] |        "  - \(.[0])", "    \(.[1:][])"    )    // .    ;
$ jq -r yamlify2 input.jsonusers:  - name:               pi    gecos:              Hypriot Pirate    sudo:               ALL=(ALL) NOPASSWD:ALL    shell:              /bin/bash    groups:             users,docker,video    plain_text_passwd:  pi    lock_passwd:        false    ssh_pwauth:         true    chpasswd:        expire:  false  - name:                 admin    gecos:                Hypriot Pirate    sudo:                 ALL=(ALL) NOPASSWD:ALL    shell:                /bin/bash    primary-group:        users    groups:               users,docker,adm,dialout,audio,plugdev,netdev,video    ssh-import-id:        None    plain_text_passwd:    pi    lock_passwd:          true    ssh_pwauth:           true    chpasswd:             {expire: false}    ssh-authorized-keys:      - ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local