Search code examples
jsonbashshellshjq

jq: Convert json to text


Below is the json content, need to create new key using jq via merging outer key with inner key and setting their value same as inner key value.

{
  "es": {
    "host": "https://es-host.ap-south-1.es.amazonaws.com",
    "user": "es_admin",
    "pass": "pa$$w0rd"
  },
  "db": {
    "host": "https://db-host.ap-south-1.es.amazonaws.com",
    "user": "db_admin",
    "pass": "pa$$w0rd"
  }   
}

Expected output:

ES_HOST="https://es-host.ap-south-1.es.amazonaws.com"
ES_USER="es_admin"
ES_PASS="pa$$w0rd"

DB_HOST="https://db-host.ap-south-1.es.amazonaws.com"
DB_USER="db_admin"
DB_PASS="pa$$w0rd"

Tried couple of combination with jq but unable to do needful. Thanks in advance.


Solution

  • One way would be to use paths to traverse the document, and getpath to retrieve the value at that path:

    jq -r '
      paths(strings) as $path
      | "\($path | map(ascii_upcase) | join("_"))=\(getpath($path) | @json)"
    '
    

    Demo

    Another way would be using .key and .value from the items provided by to_entries, employed twice thus going down exactly two levels:

    jq -r '
      to_entries[] | "\(.key | ascii_upcase)_\(.value
        | to_entries[] | "\(.key | ascii_upcase)=\(.value | @json)"
      )"
    '
    

    Demo

    Output (depending on its purpose, you might want to change @json to @sh):

    ES_HOST="https://es-host.ap-south-1.es.amazonaws.com"
    ES_USER="es_admin"
    ES_PASS="pa$$w0rd"
    DB_HOST="https://db-host.ap-south-1.es.amazonaws.com"
    DB_USER="db_admin"
    DB_PASS="pa$$w0rd"