Bash 数组的奇怪行为

Bash 数组的奇怪行为

我最近遇到了一个奇怪的脚本行为,仍然不明白数组为什么会这样表现。

以下是脚本的一部分:

for nCDATAReg in $(seq 1 4)
    do
        sTestBuffer1=$(grep -Pzoi '\/\/<\!\[CDATA\[[\s\S]*?\/\/\]\]>' $SOMEFILE | sed  -rz 's/\/\/<\!\[CDATA\[\n(.*)\/\/\]\]>/\1/g' | tr -d '\0' | sed -rz 's/InsertData\(([[:digit:]]+), [[:digit:]]+, \{(.*?)\}\)\;/\1/gm' | sed "${nCDATAReg}q;d")
        printf "\t\t\t\t\tDEBUG: Buffer is: $sTestBuffer1\t"
        aCDATA[0,$nCDATAReg]=$sTestBuffer1
        sTestBuffer2=$(grep -Pzoi '\/\/<\!\[CDATA\[[\s\S]*?\/\/\]\]>' $SOMEFILE | sed  -rz 's/\/\/<\!\[CDATA\[\n(.*)\/\/\]\]>/\1/g' | tr -d '\0' | sed -rz 's/InsertData\(([[:digit:]]+), [[:digit:]]+, \{(.*?)\}\)\;/\2/gm' | sed "${nCDATAReg}q;d")
        aCDATA[1,$nCDATAReg]=$sTestBuffer2
        printf "and second Buffer is: $sTestBufferS\t\n"
        printf "But array now contains: (${aCDATA[0,$nCDATAReg]}) and (${aCDATA[1,$nCDATAReg]})\n"
    done

文件内容为:

MORE TEXT ABOVE
</script>
    <script>//<![CDATA[
InsertData(1, 1, {VALUE1});
InsertData(3, 1, {value2});
InsertData(6, 1, {vALUE3});
InsertData(91, 1, {Value4});
//]]></script>    <div class="news-post news-post-style-full"
MORE TEXT BELOW

理论上和在控制台中,它都会生成一个包含第一个数字和花括号中字符串内容的列表。您可以在 DEBUG printf 中看到这一点,整个正则表达式一行首先放在单独的变量中,然后才放在数组单元中。但如果变量中的所有内容都是正确的,例如3 {value2},那么出于某种原因,{value2}在两种情况下都会分配给数组。

以下是输出

DEBUG: Buffer is: 1     and second Buffer is: VALUE1            But array now contains: (VALUE1) and (VALUE1)
DEBUG: Buffer is: 3     and second Buffer is: value2            But array now contains: (value2) and (value2)
DEBUG: Buffer is: 6     and second Buffer is: vALUE3            But array now contains: (vALUE3) and (vALUE3)
DEBUG: Buffer is: 91    and second Buffer is: Value4            But array now contains: (Value4) and (Value4)

我在这里遗漏了什么?(除了明显缺乏对 bash 的了解)

答案1

我花了一段时间才回来。

如果您不将其声明为关联数组,那么它就是一个数字索引数组,索引部分将被视为算术表达式。在算术表达式中,逗号分隔子表达式,返回值是最后一个子表达式的结果。

a[0,1]=x是相同的a[1]=x

a[0,1]=foo
a[1,1]=bar
declare -p a      # => declare -a a=([1]="bar")

对于关联数组,索引是一个字符串。你缺少的是declare -A arrayname

declare -A aCDATA
aCDATA[0,1]=foo
aCDATA[1,1]=bar
declare -p aCDATA     # => declare -A aCDATA=([0,1]="foo" [1,1]="bar" )

相关内容