在 bash 中为数组中的一个键关联多个值
associate multiple values for one key in array in bash
我有一个如下所示的文本文件:
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
我一直无法弄清楚如何使用 'declare -A MYMAP' 执行此操作。有什么简单的方法可以做到这一点吗?
--------更新--------
我的 key/value 对实际上是这样的:
bb126.B1 bb126.1.ms.01
bb126.B2 bb126.1.ms.02
bb126.B3 bb126.1.ms.03
bb126.B4 bb126.1.ms.04
这是 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
说明
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
:
${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.
例子
$ 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
以下脚本为逗号分隔值,您可以根据需要更改
awk -F "," '{OFS=","} 1 {if (a[]) {a[] = a[]" "} else {a[] = }} END {for (i in a) { print i,a[i]}}' input_file > Output_file
我有一个如下所示的文本文件:
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
我一直无法弄清楚如何使用 'declare -A MYMAP' 执行此操作。有什么简单的方法可以做到这一点吗?
--------更新--------
我的 key/value 对实际上是这样的:
bb126.B1 bb126.1.ms.01
bb126.B2 bb126.1.ms.02
bb126.B3 bb126.1.ms.03
bb126.B4 bb126.1.ms.04
这是 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
说明
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
:
${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.
例子
$ 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
以下脚本为逗号分隔值,您可以根据需要更改
awk -F "," '{OFS=","} 1 {if (a[]) {a[] = a[]" "} else {a[] = }} END {for (i in a) { print i,a[i]}}' input_file > Output_file