How to use multi-dimensional associative arrays in BASH
As promised, a solution in < 10 lines. Using grep with PCRE RegEx.
Introducing BAAM - [B]ASH [A]ssociative [A]rrarys in [M]ulti-dimensions
BAAM (){ # BAAM - [B]ASH [A]ssociative [A]rrarys in [M]ulti-dimensions
REGEX_STR='(^|[^\t])\t{1}'$2'((?=\t{2}[^\t])|:)\K.*?'
LEVEL=1
for PROP_NAME in "${@:3}"; do
REGEX_STR+='\t{'$((LEVEL++))'}'$PROP_NAME'((?=\t{'$(($LEVEL+1))'}[^\t])|:)\K.*?'
done
REGEX_STR+='[^\t](?=$|\t{1,'$LEVEL'}[^\t])'
echo $(echo "$1" | grep -oPe "$REGEX_STR")
}
Example of use:
#!/usr/bin/env bash
# BAAM uses BAAML, a TAB deliminated multidimensional markup
# Option 1. Inline: Pass arbitrary text containing BAAML markup into a variable
{ MY_DATA=$(</dev/stdin); } <<\EOF
SpaceX
headquarters
address:Rocket Road
city:Hawthorne
state:California
links
website:https://www.spacex.com/
flickr:https://www.flickr.com/photos/spacex/
twitter:https://twitter.com/SpaceX
elon_twitter:https://twitter.com/elonmusk
name:SpaceX
founder:Elon Musk
founded:2002
employees:8000
EOF
# Option 2. Load: cat BAAML markup into a variable
# MY_DATA="`cat ./my_baaml.txt`"
MY_DATA=${MY_DATA//$'\n'/} # Remove newlines so grep can search it in one go
# Define search function
BAAM (){ # BAAM - [B]ASH [A]ssociative [A]rrarys in [M]ulti-dimensions
REGEX_STR='(^|[^\t])\t{1}'$2'((?=\t{2}[^\t])|:)\K.*?'
LEVEL=1
for PROP_NAME in "${@:3}"; do
REGEX_STR+='\t{'$((LEVEL++))'}'$PROP_NAME'((?=\t{'$(($LEVEL+1))'}[^\t])|:)\K.*?'
done
REGEX_STR+='[^\t](?=$|\t{1,'$LEVEL'}[^\t])'
echo $(echo "$1" | grep -oPe "$REGEX_STR")
}
# Call BAAM wtih MY_DATA and each array property to reach the desired value
echo $(BAAM "$MY_DATA" SpaceX links website)
#Output: https://www.spacex.com/
If you’d like to see the process of me creating BAAM and BAAML:
Best way to simulate multidimensional arrays "objects" in BASH? - #27 by Ulfnic
This is ground floor for the project and I intend to take it a lot further. Time allowing i’ll be adding lots of features, documentation and testing.