Today, I’m going to give you some examples on how to work with associative arrays in bash / ksh.
This is not a complicated subject, but you have to be careful when writing your code because you will have extra brackets, braces, …
Support
Bash
You need version 4 or higher of bash to work with associative arrays.
You can check you version this way:
$ bash --version GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
KSH
You need “ksh93” to work with associative arrays.
Unfortunately, the is no “perfect” solution to get your version of KSH because of the various existing versions (pdksh, mksh,…) and the commands they support.
Personally, I use these 2 commands:
$ ksh --version version sh (AT&T Research) 93u+ 2012-08-01
or
$ ksh --version strings /bin/ksh | grep Version @(#)$Id: Version AJM 93u+ 2012-08-01 $
Examples
The syntax is not the same on bash and ksh. I will mention the shell used before each example.
Declare an associative array
Empty array
Bash:
declare -A MYARRAY
Ksh:
typeset -A MYARRAY
Array with values
Bash:
declare -A MYARRAY=(["key1"]=data1 ['key2']=data2 ['key3']=data3)
Ksh:
typeset -A MYARRAY=(["key1"]=data1 ['key2']=data2 ['key3']=data3)
As you can see, keys can be specified with single quotes, double quotes, or without quote. The only difference is that when you use a single quotation mark, you can not use a variable as a key because it will not be interpreted by the shell (as usual).
Your key can contain spaces but it will be harder to work with afterwards.
Remember: the keys are not necessarily sorted in memory as they were declared!
Add value to an associative array
One value
Bash & ksh:
MYARRAY[key4]=data4
Using variables:
KEY=field4 VALUE=data4 MYARRAY[$KEY]=$VALUE
Many values
Bash & ksh:
MYARRAY+=([key10]=data10 [key11]=data11)
Get a value out of an associative array
Bash & ksh:
echo ${MYARRAY[key4]}
Using variables:
KEY=field4 echo ${MYARRAY[$KEY]}
As for the population of the array, keys can be specified with single quotes, double quotes, or without quote.
Print the entire array content
Bash & ksh:
echo ${MYARRAY[@]}
Print all keys
Bash & ksh:
echo "${!MYARRAY[@]}"
Loop through an associative array
Now, you know how to print all keys and all values so looping through the array will be easy!
Loop through all key/value pair
Bash & ksh:
for key in "${!MYARRAY[@]}";do echo "Key : $key - Value : ${MYARRAY[$key]}"; done
Loop through all values
Bash & ksh:
for value in "${MYARRAY[@]}";do echo $value; done
Loop through all keys
Bash & ksh:
for key in "${!MYARRAY[@]}";do echo $key; done
Clear an associative array
Be careful, you need to unset and declare the array again! Otherwise, the old associative array will not be replaced by an empty one.
Bash:
$ echo ${MYARRAY[@]} data1 data2 data3 $ declare -A MYARRAY $ echo ${MYARRAY[@]} data1 data2 data3 $ unset MYARRAY $ echo ${MYARRAY[@]} $
Ksh:
$ echo ${MYARRAY[@]} data1 data2 data3 $ typeset -A MYARRAY $ echo ${MYARRAY[@]} data1 data2 data3 $ unset MYARRAY $ echo ${MYARRAY[@]} $
Delete key
The use of double quotation marks is considered a best practice (even if it works without them):if your key contains space and you did not put double quotation marks, you will get an error.
Bash & ksh:
$ unset MYARRAY["key3"]
Get the length of an associative array
Bash & ksh:
echo ${#MYARRAY[@]}
Test if a key exist
Bash & ksh:
if [[ -v "MYARRAY[key5]" ]] ; then # code if key exist else # code if key does not exist fi
Test if the value for a key is an empty string
Bash & ksh:
if [[ -z "${MYARRAY[key4]}" ]]; then # code if empty else # code if not empty fi
If the key does not exist, it will be considered as empty!
I hope these tips have been useful. Stay tuned for more DBA stuff!
Hi, maybe you could add one more thing: in ksh (using ksh 2020.0.0 in Ubuntu 20.04) at least, the value in an associative array can also be an array. But it seems ${MYARRAY[@]} doesn’t contain full values if they’re arrays, only the first element of the value array is printed. In this case the values need to be iterated over with keys it seems.