在bash中为数组中的一个键关联多个值

时间:2015-01-08 03:30:59

标签: arrays bash dictionary

我有一个看起来像的文本文件:

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

我想将这些映射到某种关联数组中,以便我可以访问与键2相关的所有值以及与键4相关的所有值等:

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

我已经能够通过声明-A MYMAP'来弄清楚如何做到这一点。有没有简单的方法来做到这一点?

-------- --------更新

我的键/值对实际上是这样的:

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

2 个答案:

答案 0 :(得分:2)

以下是Shell Parameter ExpansionAssociative 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

解释

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

将每个$value保存在由array[$key]分隔的,中:

  • ${array[$key]}保存以前的值(如果有的话)。
  • 如果之前的值为
  • ${array[$key]:+,},则会添加,
  • $value添加新的读取值。

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

打印与每个$key相关联的值。


来自man bash

  

$ {参数:+字}
      如果参数为null或未设置,则不替换任何内容,否则将替换word的扩展。

     

$ {!名称[@]}
  $ {!名称[*]}
      如果name是数组变量,则展开到名称中指定的数组索引(键)列表。如果name不是数组,则在设置name时扩展为0,否则为null。当使用“@”并且扩展名出现在双引号内时,每个键都会扩展为单独的单词。


实施例

$ 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

答案 1 :(得分:-1)

以下脚本用于逗号分隔值,您可以根据需要进行更改

awk -F "," '{OFS=","} 1 {if (a[$1]) {a[$1] = a[$1]" "$2} else {a[$1] = $2}} END {for (i in a)  { print i,a[i]}}'  input_file > Output_file