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.