Bash: правильный способ итерации по карте - PullRequest
4 голосов
/ 11 апреля 2010

В Bash я могу создать карту (хеш-таблицу) с этой общей конструкцией

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

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

, а затем используйте его так:

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

Но как мне лучше перебрать записи на карте? Например, в Java я бы сделал:

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

Есть ли распространенный способ сделать что-то подобное в Bash?.

Ответы [ 3 ]

11 голосов
/ 11 апреля 2010

если у вас bash 4.0, вы можете использовать ассоциативные массивы .иначе вы можете использовать awk s ассоциативные массивы

3 голосов
/ 11 апреля 2010

Вот один из способов сделать это:

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

Вот еще один:

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

И еще:

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

Кстати, "Капитолий" - это здание. Город называют столицей.

1 голос
/ 11 апреля 2010
hkeys() {
    set | grep -o "^${1}[[:alnum:]]*=" | sed -re "s/^${1}(.*)=/\\1/g"
}
for key in $(hkeys capitols) ; do
    echo $key
done

И ваша функция hget неверна. Попробуйте это:

hput capitols Smth hash
hget capitols Smth

Вторая команда должна вернуть строковый хеш, но ничего не вернула. Удалите строку «#hash» из вашей функции.

Также, echo "$(hget capitols France)" неоднозначно. Вы можете использовать hget capitols France вместо.

...