Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash: Correct way to Iterate over Map

In Bash I can create a map (hashtable) with this common construction

hput() {
  eval "$1""$2"='$3'
}

hget() {
  eval echo '${'"$1$2"'#hash}'
}

and then use it like this:

hput capitals France Paris
hput capitals Spain Madrid
echo "$(hget capitals France)"

But how do I best iterate over the entries in the map ?. For instance, in Java I would do:

for (Map.Entry<String, String> entry : capitals.entrySet()) {
  System.out.println("Country " + entry.getKey() + " capital " + entry.getValue());
}

is there a common way of accomplishing something similar in Bash ?.

like image 646
Lars Tackmann Avatar asked Apr 10 '10 23:04

Lars Tackmann


2 Answers

if you have bash 4.0 , you can use associative arrays. else you can make use of awks associative arrays

like image 126
ghostdog74 Avatar answered Sep 28 '22 07:09

ghostdog74


Here's one way to do it:

for h in ${!capitols*}; do indirect=$capitols$h; echo ${!indirect}; done

Here's another:

for h in ${!capitols*}; do key=${h#capitols*}; hget capitols $key; done

And another:

hiter() { 
    for h in $(eval echo '${!'$1'*}')
    do
        key=${h#$1*}
        echo -n "$key "
        hget $1 $key
    done
}
hiter capitols
France Paris
Spain Madrid

By the way, "capitol" is a building. A city is referred to as a "capital".

like image 25
Dennis Williamson Avatar answered Sep 28 '22 06:09

Dennis Williamson