这是我的看法:
#!/usr/bin/env bash
[[ ${BASH_VERSINFO[0]} < 4 ]] && { echo "Requires bash 4."; exit 1; }
string="${1:-banana}"
declare -A result=()
for ((i=0; i<${#string}; i++)); do
result[${string:$i:1}]="${result[${string:$i:1}]} $i"
done
declare -p result
我们的想法是,我们遍历字符串,将字符位置添加到字符串中,这些字符串是数组中的值,其下标是您感兴趣的字母。它既快速又简单,并为您提供了一个可以在之后操作的结果集,而不仅仅是将内容发送到标准输出。
我的结果是:
$ ./foo
declare -A result='([a]=" 1 3 5" [b]=" 0" [n]=" 2 4" )'
$ ./foo barber
declare -A result='([a]=" 1" [b]=" 0 3" [e]=" 4" [r]=" 2 5" )'
结果从零开始(即“b”在位置 0)。
注意这个方法的一个有趣的副作用是每个位置前面都有一个空格,所以如果你想计算一个字符出现的次数,你可以只计算空格:
$ declare -A result
$ result[a]=" 1 3 5"
$ count="${result[a]//[0-9]/}"
$ echo "${#count}"
3
$
我不知道您打算如何处理这些数据,但如果您愿意,您可以轻松地将这些字符串结果转换为它们自己的数组,以便在 bash 中更轻松地处理。
请注意,关联数组是在 bash 版本 4 中引入的。