3

I want to have a function in bash, which create a Dictionary as a local variable. Fill the Dictionary with one element and then return this dictionary as output.

Is the following code correct?

function Dictionary_Builder ()
{
local  The_Dictionary
unset  The_Dictionary
declare -A The_Dictionary
The_Dictionary+=(["A_Key"]="A_Word")
return $The_Dictionary
}

How can I access to the output of the function above? Can I use the following command in bash?

The_Output_Dictionary=Dictionary_Builder()
Admia
  • 1,025
  • 3
  • 12
  • 24

2 Answers2

3

To capture output of a command or function, use command substitution:

The_Output_Dictionary=$(Dictionary_Builder)

and output the value to return, i.e. replace return with echo. You can't easily return a structure, though, but you might try returning a string that declares it (see below).

There's no need to use local and unset in the function. declare creates a local variable inside a function unless told otherwise by -g. The newly created variable is always empty.

To add a single element to an empty variable, you can assign it directly, no + is needed:

The_Dictionary=([A_Key]=A_Word)

In other words

#!/bin/bash
Dictionary_Builder () {
    declare -A The_Dictionary=([A_Key]=A_Word)
    echo "([${!The_Dictionary[@]}]=${The_Dictionary[@]})"
}

declare -A The_Output_Dictionary="$(Dictionary_Builder)"
echo key: ${!The_Output_Dictionary[@]}
echo value: ${The_Output_Dictionary[@]}

For multiple keys and values, you need to loop over the dictionary:

Dictionary_Builder () {
    declare -A The_Dictionary=([A_Key]=A_Word
                               [Second]=Third)
    echo '('
    for key in  "${!The_Dictionary[@]}" ; do
        echo "[$key]=${The_Dictionary[$key]}"
    done
    echo ')'
}

declare -A The_Output_Dictionary="$(Dictionary_Builder)"
for key in  "${!The_Output_Dictionary[@]}" ; do
    echo key: $key, value: ${The_Output_Dictionary[$key]}
done
choroba
  • 231,213
  • 25
  • 204
  • 289
  • I understood this code, expect the reason for using double quotes in 4th and 6th lines – Admia Nov 28 '15 at 20:39
  • @Mahdi: Try removing the first pair of double quotes: you'll get a syntax error (unquoted `(`). The second pair might not be needed in this case, but it doesn't hurt. – choroba Nov 28 '15 at 20:42
  • I am defining a function based on your code. However, I get the following error when I execute my script. ./test.sh: line 4: syntax error near unexpected token `(' ./test.sh: line 4: ` declare -A The_Dictionary =([Key1]=Word1)' – Admia Nov 28 '15 at 21:18
  • @Mahdi: Does my script work for you when copied and pasted? – choroba Nov 28 '15 at 21:27
  • Both your code and mine are working properly now. Thanks Choroba. – Admia Nov 28 '15 at 21:33
  • In your current code, only one pair of (Key, Word) is added to the dictionary. Please add 2 more pairs of (Key, Word) to the dictionary. You will see that the values at the last line of your code are not printed properly. More precisely, only one value out of 3 available values is printed. – Admia Nov 28 '15 at 21:55
  • @Mahdi: That wasn't part of the spec. Check the updated answer. – choroba Nov 28 '15 at 22:01
2

The answer by @choroba is what I was looking for. However, my dictionary values also had white spaces in them and the above answer didn't work outright. What worked was a minor variation of the above answer.

#!/bin/bash

function Dictionary_Builder() {
    declare -A dict=(['title']="Title of the song"
                 ['artist']="Artist of the song"
                 ['album']="Album of the song"
                )

    echo '('
    for key in  "${!dict[@]}" ; do
        echo "['$key']='${dict[$key]}'"
    done
    echo ')'
}

declare -A Output_Dictionary="$(Dictionary_Builder)"

for key in  "${!Output_Dictionary[@]}" ; do
    echo "${key}: '"${Output_Dictionary[$key]}"'"
done

Note the extra single quotes on the 2nd echo line which made it possible to output values with whitespaces in them.

ASarkar
  • 469
  • 5
  • 16