LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   [bash] indirect array reference to array with values containing spaces (https://www.linuxquestions.org/questions/linux-software-2/%5Bbash%5D-indirect-array-reference-to-array-with-values-containing-spaces-812166/)

Meson 06-04-2010 11:03 AM

[bash] indirect array reference to array with values containing spaces
 
This _almost_ works. I just can't quite get it to honor the spaces.

Code:

#!/bin/bash

profiles=(
        PROFILE_ONE
)

PROFILE_ONE=(setting1 "setting number 2")

for p in "${profiles[@]}"; do

        echo "original p:        ${p}"

        eval p=(\${${p}[@]})

        echo "new p:              ${p}"
        echo "new p contents:    ${p[@]}"

        echo "new p split:"

        for o in "${p[@]}"; do
                echo "                    $o"
        done
done

echo
echo


rweaver 06-04-2010 11:21 AM

You could use IFS to do this... http://tldp.org/LDP/abs/html/internalvariables.html (Note change to PROFILE_ONE)
Code:

#!/bin/bash
IFS_ORIG=$IFS
IFS=","
profiles=(
        PROFILE_ONE
)

PROFILE_ONE=(setting1, "setting number 2")

for p in "${profiles[@]}"; do

        echo "original p:        ${p}"

        eval p=(\${${p}[@]})

        echo "new p:              ${p}"
        echo "new p contents:    ${p[@]}"

        echo "new p split:"

        for o in "${p[@]}"; do
                echo "                    $o"
        done
done

echo
echo
IFS=$IFS_ORIG


Meson 06-04-2010 12:43 PM

Thanks,

One oddity about this though, is that newlines still work as a separator. Can anyone explain this?

Just for anyone coming across this, you only need to change the IFS when going over the loop. Also you need to check for some blank entries:

Code:

#!/bin/bash

profiles=(
        PROFILE_ONE
)

PROFILE_ONE=(setting1, "setting number 2")

IFS_ORIG=$IFS
IFS=","
for p in "${profiles[@]}"; do

        echo "original p:        ${p}"

        eval p=(\${${p}[@]})

        echo "new p:              ${p}"
        echo "new p contents:    ${p[@]}"

        echo "new p split:"

        for o in "${p[@]}"; do
                [ "$o" == "" ] && continue
                echo "                    $o"
        done
done
IFS=$IFS_ORIG

echo
echo


Meson 06-04-2010 01:01 PM

Actually, I still have a problem with this. It has to do with quoted strings:

Code:

#!/bin/bash

profiles=(
        PROFILE_ONE
)

PROFILE_ONE=(
        setting1,
        "setting number 2",
        \"setting number 3\"
)

IFS_ORIG=$IFS
IFS=","
for p in "${profiles[@]}"; do

        echo "original p:        ${p}"

        eval p=(\${${p}[@]})

        echo "new p:              ${p}"
        echo "new p contents:    ${p[@]}"

        echo "new p split:"

        for o in "${p[@]}"; do
                [ "$o" == "" ] && continue
                echo "                    $o"
        done
done
IFS=$IFS_ORIG

echo
echo

Here, setting 2 id displayed as an atom without quotes, setting 3 is displayed as 3 atoms, the first one leading with a quote and the third one trailing with a quote.

catkin 06-04-2010 01:02 PM

The code can be tightened up a little like this, assuming IFS starts with the default value (and legibility is not a prime concern!)
Code:

#!/bin/bash

profiles=(
        PROFILE_ONE
)

PROFILE_ONE=(setting1, "setting number 2")

#IFS_ORIG=$IFS
IFS=","
for p in "${profiles[@]}"; do

        echo "original p:        ${p}"

        eval p=(\${${p}[@]})

        echo "new p:              ${p}"
        echo "new p contents:    ${p[@]}"

        echo "new p split:"

        for o in "${p[@]}"; do
                # [ "$o" == "" ] && continue
                [ "$o" == "" ] || echo "                    $o"
        done
done
#IFS=$IFS_ORIG
unset IFS

Note: If IFS is unset bash behaves in all respects as if it had the default value.

catkin 06-04-2010 01:06 PM

Quote:

Originally Posted by Meson (Post 3992618)
Actually, I still have a problem with this.
...
Here, setting 2 id displayed as an atom without quotes, setting 3 is displayed as 3 atoms, the first one leading with a quote and the third one trailing with a quote.

Why is that a problem? PROFILE_ONE as initialised is a five element array. AIUI the described display is correct ... ???

Meson 06-04-2010 01:42 PM

The example above displays as:
Code:

setting1
setting number 2
"setting
number
3"

This is not what I want. It should be:

Code:

setting1
setting number 2
"setting number 3"


catkin 06-04-2010 01:45 PM

But that is not the content of PROFILE_ONE when it is initialised with
Code:

PROFILE_ONE=(
        setting1,
        "setting number 2",
        \"setting number 3\"
)


Meson 06-04-2010 02:02 PM

I don't know what you mean by that. If I set IFS=, then I expect for that declaration of PROFILE_ONE to have 3 items, not 5.

catkin 06-04-2010 09:38 PM

Hadn't the IFS=, been moved after the array initialisation? And anyway setting IFS=, and then using "," as an array element separator doesn't work:
Code:

c@CW8:~$ IFS=,
c@CW8:~$ x=(a, b,c)
c@CW8:~$ echo "'${x[0]}'"
'a,'
c@CW8:~$ echo "'${x[1]}'"
'b,c'



All times are GMT -5. The time now is 06:49 AM.