associate multiple values for one key in array in bash

前端 未结 2 1343
情书的邮戳
情书的邮戳 2021-02-04 22:10

I have a text file that looks like:

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

I would like to map these into some sort of associative ar

2条回答
  •  你的背包
    2021-02-04 23:08

    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 ffffdd
    2 eeee
    2 ffff
    4 gggg
    
    $ ./script.sh 
    1->aaaa
    2->bbbb,eeee,ffff
    3->cccc
    4->ffffdd,gggg
    

提交回复
热议问题