0

I've recently encountered a strange script behavior and still don't understand y the array behaves this way.

Here is a piece of the script:

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

and file content is:

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

In theory and in console, its produce a list of the first digit and the content of the string in curly braces. You can see this in DEBUG printf's, the entire regex oneliner is first placed in separate variables and only then in an array cell. But if everything is correct in the variable, like 3 {value2}, then for some reason {value2} is assigned to the array in both cases.

Here is output

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)

What am I missing here? (besides the obvious poor knowledge of bash)

1
  • Did you declare the array with declare -A aCDATA to let bash know it's an associative array? (answer with more explanation forthcoming) Jan 27 at 17:16

1 Answer 1

1

Took me a while to get back.

If you don't declare it as an associative array then it's a numerically-indexed array for which the index part is treated as an arithmetic expression. In an arithmetic expression, commas separate sub-expressions and the return value is the result of the last subexpression.

a[0,1]=x is the same as a[1]=x

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

For an associative array, the index is a string. What you're missing is 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" )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.