Set data structure equivalent in bash shell?

If all you care about is a set of strings, you can just use an associative array ("hashmap"):

declare -A hm
hm[hello]=1
hm[world]=1
hm[hello]=1
if [ "${hm[hello]}" ] ; then ... ; fi

All you care about is whether there's something associated with the key or not. The value doesn’t matter, we only care that there’s a non-empty string there (so you can "delete" an entry by setting it to an empty string).

This would be analogous to using a HashMap<String,Object> to represent a set (which is actually what Java’s HashSet does, in fact).

These associative arrays are available in Bash 4 and later, and also in zsh and ksh. They don't work in 3-series Bash versions and earlier, including macOS’s Bash 3.2.


There is no POSIX equivalent. You could simulate the effect using eval if your strings are suitably restricted, or have a natural transformation to valid variable names:

hm_hello=1
hm_world=1
key=test
eval "hm_$key=1"
if [ "$(eval hm_$key)" ] ; then ... ; fi

You could also use a temporary file and grep, for example, or even lots of temporary files and the filesystem as a key store.


It's also possible (perhaps likely) that using some other tool or language is more suitable than shell script. At a minimum, awk is available on all POSIX systems and it does support string-keyed associative arrays.

If you really do have complex data-structure needs a conventional general-purpose language may be still more appropriate. Perl and Python are also widely available.