【问题标题】:Iterate array in bash v.3在 bash v.3 中迭代数组
【发布时间】:2017-07-02 19:44:43
【问题描述】:

我有 file.properties,其中定义了键和值:

key1=value1 value2 value3
key2=value4 value5 value6
key3=value7 value8 value9

我想将文件中的行加载到数组中。由于 bash 3,我无法使用 declare -A 创建关联数组。

在 bash 4 中,我的代码是:

conf="./file.properties"

init() {
local configiration=$1
if [ -f "$conf" ]
then
    while IFS='=' read -r key value
    do
        configuration[ ${key} ]=$value
    done < "$conf"
fi}
declare -A configuration
init configuration

KEY="key value from file"
#KEY="key1" or KEY="key2" or KEY="key3"
SERVERS=${configuration[ $KEY ]}

我想在 bash 3 中做同样的工作。

conf="./file.properties"
init () {
key=()
value=()
if [ -f "$conf" ]
then
    while IFS='=' read -r key value
    do
        key+=("$key")
        value+=("$value")
    done < "$conf"
fi}
init
KEY="key value from file"
#KEY="key1" or KEY="key2" or KEY="key3"
for ((i = 0; i < ${#key[@]}; i++))
    do
    if [ "${key[$i]}" == "$KEY" ]; 
    then
        echo "values: ${value[i]}"
    fi
done

在这两种情况下,我得到相同的输出,例如:

value1 value2 value3

我的 bash 3 代码是否正确或需要修改?

【问题讨论】:

  • 当你说KEY="key value from file" 它实际上包含什么?你能提供它以便我们实际测试它吗?
  • 此外,它无法重现您声称的问题,运行 KEY="key1",KEY="key2",KEY="key3"bash v3.0 代码产生的输出为 values: value1 value2 value3, values: value4 value5 value6values: value7 value8 value9分别!这不是你想做的吗?那你有什么问题?
  • 如果你只是问你是否用一对索引数组正确模拟了一个关联数组,答案大部分是肯定的。
  • 我只是在问它是否正确(不是语法上而是逻辑上)或者它是否会更好。我不是脚本专家

标签: arrays bash shell


【解决方案1】:

这对我来说是正确的,因为考虑到您之前刚刚创建了数组,并且知道数组的键将在 0,1,...,n-1 中用于大小为 n 的数组,因此您使用适当的方式遍历数组。 array+=(elements) 运算符始终将 elements 放入 array,从 array 的最后一个索引 + 1 开始。

我会以不同方式遍历数组的唯一情况是,如果不能保证索引在[0,n) 中。例如:

declare -ai roots=();
declare -i x y;
for ((x=0; x<4; roots[x*x]=x,++x)) do :; done;
for y in "${!roots[@]}"; do
    printf 'sqrt(%d) = %d\n' $y ${roots[y]};
done;

通过使用"${!roots[@]}"扩展roots的索引来遍历它,我们得到以下输出:

sqrt(0) = 0
sqrt(1) = 1
sqrt(4) = 2
sqrt(9) = 3

在这种情况下,我们必须避免算术 for 循环以避免发生类似以下情况:

$ for((i=0;i<${#roots[@]};++i)); do echo "${roots[i]}"; done;
0
1
 
 

我要做的唯一改变是使用[[ 而不是[ 来执行字符串比较,因为它是一个bash 内置函数,通常使用起来更安全、更高效。另外,我相信您需要在 } 之前使用换行符或 ; 来关闭您的 init 函数。

【讨论】:

    猜你喜欢
    • 2019-01-25
    • 2018-03-01
    • 2016-06-03
    • 2021-04-11
    • 2011-03-07
    • 1970-01-01
    相关资源
    最近更新 更多