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? 😊