Sean Walton
Sean Walton

Reputation: 146

bash associative arrays--variable containing value pair

I have a file that looks like this:

stringtests (6 tests)
alphatests (1 tests)
arraytests (100 tests)

I can extract and translate into:

["stringtests"]="6"
["alphatests"]="1"
["arraytests"]="100"

I place these in a variable ("tests"):

~> tests="[\"stringtests\"]=\"6\" [\"alphatests\"]=\"1\" [\"arraytests\"]=\"100\""

Then I try to put them in an associative array using the variable I get an error:

~> declare -A arr=( $tests )
-bash: arr: ["stringtests"]="6": must use subscript when assigning associative array
-bash: arr: ["alphatests"]="1": must use subscript when assigning associative array
-bash: arr: ["arraytests"]="100": must use subscript when assigning associative array

"eval" doesn't work either:

declare -A arr=( $(eval echo $tests) )
-bash: arr: [stringtests]=6: must use subscript when assigning associative array
-bash: arr: [alphatests]=1: must use subscript when assigning associative array
-bash: arr: [arraytests]=100: must use subscript when assigning associative array

But, if I put the values directly it works:

~> declare -A arr=( ["stringtests"]="6" ["alphatests"]="1" ["arraytests"]="100" )
~> echo ${arr[@]}
1 100 6
~> echo ${!arr[@]}
alphatests arraytests stringtests

Is it even possible to do this?

Upvotes: 2

Views: 968

Answers (2)

glenn jackman
glenn jackman

Reputation: 247192

I would avoid the temp variable altogether, and populate the array while you're parsing the file

declare -A arr
while IFS= read -r line; do 
    # bash regex: the literal bits are quoted
    if [[ $line =~ (.+)" ("([0-9]+) ]]; then 
        arr["${BASH_REMATCH[1]}"]="${BASH_REMATCH[2]}"
    fi
done < file
declare -p arr
declare -A arr='([alphatests]="1" [arraytests]="100" [stringtests]="6" )'

Upvotes: 1

Cyrus
Cyrus

Reputation: 88939

Replace

declare -A arr=( $tests )

with

declare -A arr='('$tests')'

tests="[\"stringtests\"]=\"6\" [\"alphatests\"]=\"1\" [\"arraytests\"]=\"100\""
declare -A arr='('$tests')'
declare -p arr

Output:

declare -A arr='([alphatests]="1" [arraytests]="100" [stringtests]="6" )'

Upvotes: 4

Related Questions