How to Easily Create a JSON File in Bash

There are always lots of ways to do things, especially when coding. But some ways are better than others.

1 min read
How to Easily Create a JSON File in Bash
Photo by RealToughCandy.com from Pexels.

Last week, I had to work on a complex legacy system where some Bash scripts are used to produce JSON files for an API. After fixing a bug on one of these scripts, I saw a line that bothered me:

echo "{\"filename\":\"$filename\",\"base64\":\"$base64\", \"width\":\"$width\",\"height\":\"$height\"}" > $destination

There are a lot of escapes, aren't there? A missing \ or " and the JSON produced would be invalid. Not great if you need to edit that line to add a property, is it?

There must be an easier way to create a JSON file, right? 🤔

As usual, I found the answer I was looking for on StackOverflow with the jq utility:

# Obtaining the file in base64 format without any newline to have valid JSON
base64=$(base64 "${filename}" --wrap 0)

# Obtaining the dimensions of the image
width=$(identify -format '%w' "${filename}")
height=$(identify -format '%h' "${filename}")

# Generating a JSON string (https://stackoverflow.com/a/48470227)
json_string=$(
  jq --null-input \
    --arg base64 "${base64}" \
    --arg filename "${filename}" \
    --arg height "${height}" \
    --arg width "${width}" \
    '{base64: $base64, filename: $filename, height: $height, width: $width}'
)

# Creating the JSON file
echo $json_string > "${destination}"

Even though the command has a lot more lines, I think it's more understandable and less likely to get it wrong. 😎

On the same page, someone else mentions that if  you have a single-level object and a version of jq greater than 1.6, you can use $ARGS.named instead.

# Generating a JSON string (https://stackoverflow.com/a/68591585)
json_string=$(
  jq --null-input \
    --arg base64 "${base64}" \
    --arg height "${height}" \
    --arg width "${width}" \
    --arg filename "${filename}" \
    '$ARGS.named'
)

If you need to add, change or remove a property, you can do it now by editing only a single line, isn't that nice? 🤗

It's always fun to discover a new tool, isn't it? 😊