PerseP
PerseP

Reputation: 1197

Bash Use associative arrays with keys with quotes

I'm trying out the associative arrays in bash 5.1.16 by loading a file into a hash table like so but it doesn't work if the file values are in quotes it returns null:

#!/bin/bash -e

declare -A dict

while read key; do
    dict[$key]=$key
done < test2.txt

echo "This doesn't work ${dict[a]} ${dict[b]}"

test2.txt file being:

"a"
"b"
"c"

But if I remove the quotes in test2.txt it works fine. But what I can't understand is if I assign them manually with and without quotes both ways work.

#!/bin/bash -e

declare -A dict

dict[f]="f"
dict["g"]="g"

echo "This works ${dict["f"]} ${dict["g"]}"

My understanding from other SO answers is that the keys shouldn't be quoted but as you see in the previous example they work with quotes. So how can I load the file if the keys have quotes or the should have them removed before loading?

Upvotes: 0

Views: 302

Answers (1)

jhnc
jhnc

Reputation: 16762

The shell uses " to signify that word-splitting should not occur in some contexts where parameter expansion occurs. The double-quotes are not treated as part of the data that they surround.

When reading data from the file, the " are part of the data itself, in the same way that commands are not executed.

cat >test3.txt <<'EOD'
echo   hello $world
"a"
a
EOD

declare -A dict2

while read key; do
    dict2[$key]=$key
done < test3.txt

dict2[f]="f"
dict2["g"]="g"

dict2[\"h\"]=\"h\"
dict2['"i"']='"i"'

declare -p dict2

outputs (wrapped/indented for clarity here):

declare -A dict2=(
    ["echo   hello \$world"]="echo   hello \$world"
    [g]="g"
    [f]="f"
    [a]="a"
    ["\"a\""]="\"a\""
    ["\"i\""]="\"i\""
    ["\"h\""]="\"h\""
)

More precisely, from the bash manual, Quoting:

Quoting is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to disable special treatment for special characters, to prevent reserved words from being recognized as such, and to prevent parameter expansion.

Note that read when used without -r may alter the data read, and if given multiple variables will perform word-splitting.

Upvotes: 3

Related Questions