Bash:迭代变量名

时间:2016-09-29 19:57:07

标签: arrays bash

我正在编写一个bash脚本来分析一些文件。在第一次迭代中,我创建了关联数组,其中包含分析的每个类别的字数。事先不知道这些类别,因此这些关联数组的名称是可变的,但都具有相同的前缀<html><head><meta http-equiv="Pragma" content="no-cache"/> <script> a huge javascript function <noscript>Please enable JavaScript to view the page content.</noscript> 。关联数组有一个单词作为键,它在该类别中的出现次数为值。

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

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

count_*

1 个答案:

答案 0 :(得分:2)

现代(bash 4.3+)方法使用&#34; namevars&#34;,一个从ksh借来的设施:

for _count_var in "${!count_@}"; 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]}"用于在名为foo的关联数组中查找项count_var;同样,count[foo]=bar将分配给同一个项目。 unset -n count然后删除此映射。

在bash 4.3之前:

for _count_var in "${!count_@}"; 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_*模式不匹配。