从循环内更改数组元素值不会按预期工作

时间:2018-02-27 07:17:03

标签: arrays bash shell scripting

我有一个shell脚本打印功能,如下所示:

print_status()
{
 echo "$1|$2|$3|$4"
 paramArr=("$@")
 for i in "${#paramArr[@]}"
 do
   if [[ -z ${paramArr[i]} ]];
   then
       paramArr[i]="Unknown"
   fi
 done
 echo "${paramArr[*]}"
}

该函数应该打印4个值,使用" |"作为分隔符。我将print语句保留在函数顶部,只是为了显示实际值的打印方式。

我还想检查每个参数是否为此函数,如果是空值(即变量实际上不包含任何内容),则打印"未知"。我希望通过上面的数组paramArr完成此操作。但它并没有像预期的那样发挥作用。

示例:

Output1:
Running|162.103.172.46|3.345|-0.076
Running 162.103.172.46 3.345 -0.076 Unknown

Expected Output 1:
Running|162.103.172.46|3.345|-0.076
Running 162.103.172.46 3.345 -0.076 <-- With a "|" instead of space


Output2:
Not Running|||
Not Running    Unknown

Expected Output2:
Not Running|||
Not Running Unknown Unknown Unknown <-- With a "|" instead of space

我的功能到底出了什么问题?

1 个答案:

答案 0 :(得分:1)

你有几个问题。首先,您要计算从零到元素数量的数组索引。当它是4然后你从0 - 4,这是5个元素,所以你得到一个额外的。当它少于4时,它将不会添加“未知”,因为你没有进行足够的迭代。

其次,当您在引号内使用[*]打印数组时,元素之间的分隔符是$IFS的第一个字符,默认情况下是空格:

print_status()
{
    echo "$1|$2|$3|$4"
    paramArr=("$@")

    for ((i=0; i < 4; i++))
    do
        if [[ -z ${paramArr[i]} ]];
        then
            paramArr[i]="Unknown"
        fi
    done

    oldIFS="$IFS"
    IFS='|'
    echo "${paramArr[*]}"
    IFS="$oldIFS"
}

print_status Running 162.103.172.46 3.345 -0.076
print_status 'Not Running'

给出:

Running|162.103.172.46|3.345|-0.076
Running|162.103.172.46|3.345|-0.076
Not Running|||
Not Running|Unknown|Unknown|Unknown