Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

associate multiple values for one key in array in bash

I have a text file that looks like:

1 aaaa
2 bbbb
3 cccc
4 dddd
2 eeee
2 ffff
4 gggg

I would like to map these into some sort of associative array so that I can access, for example, all the values associated with the key 2 and all the values associated with the key 4, etc.:

1->aaaa
2->bbbb,eeee,ffff
3->cccc
4->dddd,gggg

I haven't been able to figure out how to do this with 'declare -A MYMAP'. Is there some easy way to do this?

--------update--------

my key/value pairs look like this actually:

bb126.B1 bb126.1.ms.01
bb126.B2 bb126.1.ms.02
bb126.B3 bb126.1.ms.03
bb126.B4 bb126.1.ms.04

1 Answers

Here's a solution with Shell Parameter Expansion and Associative Arrays:

# store
declare -A array # this is the only update
while read key value; do
    array[$key]="${array[$key]}${array[$key]:+,}$value"
done < file
# print
for key in "${!array[@]}"; do echo "$key->${array[$key]}"; done

Explanation

array[$key]="${array[$key]}${array[$key]:+,}$value"

saves each $value in array[$key] separated by ,:

  • ${array[$key]} save previous value(s) (if any).
  • ${array[$key]:+,} adds a , if there's a previous value.
  • $value adds the new read value.

for key in "${!array[@]}"; do echo "$key->${array[$key]}"; done

prints the values associated to each $key.


From man bash:

${parameter:+word}
If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.

${!name[@]}
${!name[*]}
If name is an array variable, expands to the list of array indices (keys) assigned in name. If name is not an array, expands to 0 if name is set and null otherwise. When ‘@’ is used and the expansion appears within double quotes, each key expands to a separate word.


Example

$ cat file
1 aaaa
2 bbbb
3 cccc
4 dddd
2 eeee
2 ffff
4 gggg

$ ./script.sh 
1->aaaa
2->bbbb,eeee,ffff
3->cccc
4->dddd,gggg
like image 157
whoan Avatar answered May 30 '26 05:05

whoan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!