Bash: the correct way to reinstall the card

In Bash, I can create a map (hash table) with this general construct

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 what is the best way to iterate over entries on a map? For example, 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 general way to do something like this in Bash ?.

+4
source share
3 answers

if you have bash 4.0 you can use associative arrays . otherwise you can use awk associative arrays

+10
source

Here is one way to do this:

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

Here is another:

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

And further:

 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, the "capital" is a building. The city is called the "capital".

+3
source
 hkeys() { set | grep -o "^${1}[[:alnum:]]*=" | sed -re "s/^${1}(.*)=/\\1/g" } for key in $(hkeys capitols) ; do echo $key done 

And your hget function is incorrect. Try the following:

 hput capitols Smth hash hget capitols Smth 

The second command should return a hash of a line, but returned nothing. Remove the line "#hash" from your function.

In addition, echo "$(hget capitols France)" ambiguous. Instead, you can use hget capitols France .

+1
source

Source: https://habr.com/ru/post/1306587/


All Articles