Skip to content

Instantly share code, notes, and snippets.

@chgeuer
Last active November 19, 2021 22:35
Show Gist options
  • Save chgeuer/c9c3dd28a30f632df0838daa06eea820 to your computer and use it in GitHub Desktop.
Save chgeuer/c9c3dd28a30f632df0838daa06eea820 to your computer and use it in GitHub Desktop.
Creates a JSON structure in the shell

A purely functional JSON processing pipeline using jq in bash

It starts with an empty JSON object, and each jq step in the pipeline further augments the structure. In case you want to step-by-step build up a JSON string in a shell.

How does it work

The --arg binds a string variable from bash to the jq-variable x.

The jq expression ($x | fromjson) parses the string into whatever JSON would be appropriate. So the bash variable true becomes the proper true boolean in the JSON. If we only would use $x (instead of ($x | fromjson)), the bash variable true would become the JSON string "true".

The script

#!/bin/bash

numba=1

literal='{"c": [1,2,3,"foo"]}'

someShellStr=https://twitter.com/chgeuer

someBool=true

json="$( echo "{}" | \
  jq --arg x "${numba}"    '.some.number=($x | fromjson)'              | \
  jq --arg x "${literal}"  '.some.deeply.nested.stuff=($x | fromjson)' | \
  jq --arg x "${someBool}" '.some.deeply.nested.bool=($x | fromjson)' | \
  jq --arg x "${someShellStr}" '.someShellStr=$x'   )"

echo "${json}"

The output

{
  "some": {
    "number": 1,
    "deeply": {
      "nested": {
        "stuff": {
          "c": [
            1,
            2,
            3,
            "foo"
          ]
        },
        "bool": true
      }
    }
  },
  "someShellStr": "https://twitter.com/chgeuer"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment