2

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?

3
  • Need eval before declare not in the subshell.eval declare -A arr=( $tests ). Fails because = is evaluated before variable expansion so array sees ["stringtests"]="6" as a single string. Commented Oct 31, 2017 at 16:34
  • @123, eh? eval can be avoided entirely here, and when it can be avoided it should. Commented Oct 31, 2017 at 17:26
  • @CharlesDuffy Just pointing out the issue with their command, not suggesting it was the best option. Commented Oct 31, 2017 at 17:37

2 Answers 2

4

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" )'
Sign up to request clarification or add additional context in comments.

6 Comments

probably safer to write declare -A arr="($tests)" so that the variable is quoted.
@Cyrus How does escaping/quoting the parenths make it interpret the contents differently? Is there any documentation or am I missing something obvious?
@123: There are no details known to me.
@Cyrus Did you just stumble upon it then? I can't see why it would make any difference. Why would the = be interpreted only if () are escaped?
@123: I stumbled upon it when I was looking at the output of: declare -p arr.
|
1

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" )'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.