bash 在bash中为数组中的一个键关联多个值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27832452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
associate multiple values for one key in array in bash
提问by whoan
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.:
我想将这些映射到某种关联数组中,以便我可以访问,例如,与键 2 关联的所有值和与键 4 关联的所有值等:
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?
我一直无法弄清楚如何使用“declare -A MYMAP”来做到这一点。有什么简单的方法可以做到这一点吗?
--------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
回答by whoan
Here's a solution with Shell Parameter Expansionand Associative Arrays:
这是带有Shell Parameter Expansion和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 ,
:
将每个保存$value
在array[$key]
分隔开,
:
${array[$key]}
save previous value(s) (if any).${array[$key]:+,}
adds a,
if there's a previous value.$value
adds the new read value.
${array[$key]}
保存以前的值(如果有)。${array[$key]:+,}
,
如果有以前的值,则添加一个。$value
添加新的读取值。
for key in "${!array[@]}"; do echo "$key->${array[$key]}"; done
prints the values associated to each $key
.
打印与每个 关联的值$key
。
From man bash
:
来自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.
${parameter:+word}
如果参数为空或未设置,则不替换任何内容,否则替换单词的扩展。${!name[@]}
${!name[*]}
如果 name 是数组变量,则扩展为 name 中指定的数组索引(键)列表。如果 name 不是数组,则在设置 name 时扩展为 0,否则为 null。当使用“@”并且扩展出现在双引号内时,每个键都扩展为一个单独的词。
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
回答by Viju
The below script is for comma separated value, you can change as per your need
以下脚本用于逗号分隔值,您可以根据需要进行更改
awk -F "," '{OFS=","} 1 {if (a[]) {a[] = a[]" "} else {a[] = }} END {for (i in a) { print i,a[i]}}' input_file > Output_file