2016-09-29 333 views
0

我在写一个bash脚本来分析一些文件。在第一次迭代中,我为每个分析的类别创建了包含字数的关联数组。这些类别事先不知道,因此这些关联数组的名称是可变的,但都使用相同的前缀count_$category。关联数组有一个单词作为关键字,其出现次数在该类别中作为值计数。Bash:遍历变量名称

在对所有文件进行分析后,我必须总结每个类别的结果。我可以使用${count_*}迭代变量名称,但是如何访问这些变量名称后面的关联数组?对于每个关联数组(每个count_*变量),我应该遍历单词和它们的计数。

我已经尝试过像这样的间接访问,但它不工作:

for categorycount in ${count_*} # categorycount now holds the name of the associative array variable for each category 
do 
    array=${!categorycount} 
    for word in ${!array[@]} 
    do 
     echo "$word occurred ${array[$word]} times" 
    done 
done 
+1

你可以发布[mcve]吗?例如,[编辑]您的代码来填充2个关联数组并向我们展示您的期望。 –

+0

解决:我终于找到了一个SO问题回答这个问题 http://stackoverflow.com/a/13306800/5324593 – OKamers

+0

bash的哪个版本? 4.3有一个新的设施直接点。 –

回答

2

现代(4.3及更高版本的bash)的方式使用“namevars”,从KSH借来设施:

for _count_var in "${[email protected]}"; do 
    declare -n count=$_count_var     # make count an alias for $_count_var 
    for key in "${!count[@]}"; do     # iterate over keys, via same 
     echo "$key occurred ${count[$key]} times" # extract value, likewise 
    done 
    unset -n count        # clear that alias 
done 

declare -n count=$count_var允许"${count[foo]}"用于查找名为count_var的关联数组中的项目foo;同样,count[foo]=bar将分配给相同的项目。 unset -n count然后删除此映射。


之前打坏4.3:

for _count_var in "${[email protected]}"; do 
    printf -v cmd '_count_keys=("${!%q[@]}")' "$_count_var" && eval "$cmd" 
    for key in "${_count_keys[@]}"; do 
    var="$_count_var[$key]" 
    echo "$key occurred ${!var} times" 
    done 
done 

使用注意事项的%q,而不是直接代变量名转换为字符串,以产生命令,以eval。尽管在这种情况下我们可能是安全的(因为可能的变量名称集是受限制的),遵循这种做法减少了需要考虑的上下文的数量,以确定间接扩展是否安全。


在这两种情况下,注意,内部变量(_count_var_count_keys等)使用不与count_*模式相匹配的名字。