loading...

Representation of a Data Structure Like an Array of Hash Tables in Bash Using jq

yuyatakeyama profile image Yuya Takeyama ・1 min read

Have you ever needed a Hash Table in Bash?
I needed it when I was writing a deploy script.

I found that Bash 4 has a data structure called Dictionary.
https://stackoverflow.com/questions/1494178/how-to-define-hash-tables-in-bash

But the version of Bash in my laptop is 3.2.57 and I couldn't use it.
Of course, it's easy to update the Bash.
But we may need to work on environments with an older version of it.
So I thought up about the other way.

How to

#!/bin/bash -eu

# A data structure like an array of hash tables
# Strictly, it's a stream of JSONs
PARAMETERS=$(cat <<_EOT_
{
  "foo":"FOO 1",
  "bar":"BAR 1"
}
{"foo":"FOO 2","bar":"BAR 2"}
{
  "foo": "フー",
  "bar": "\u30d0\u30fc"
}
_EOT_
)

# Transform into a line-delimited JSONs
PARAMETERS=$(echo "${PARAMETERS}" | jq . --monochrome-output --compact-output)

# Enumerate JSONs and output foo and bar of each item
while IFS='' read -r param || [[ -n "${param}" ]]; do
  foo=$(echo "${param}" | jq .foo -r)
  bar=$(echo "${param}" | jq .bar -r)

  echo "foo=${foo}"
  echo "bar=${bar}"

  echo "---"
done < <(echo "${PARAMETERS}")
$ bash json_stream.sh
foo=FOO 1
bar=BAR 1
---
foo=FOO 2
bar=BAR 2
---
foo=フー
bar=バー
---
  • Build a JSON as a string using heredoc
  • Transform the JSON into a line-delimited JSONs
  • Read a JSON from each line
  • Retrieve each property like jq .foo in the loop

Hope you enjoyed it!

Discussion

pic
Editor guide