I'm trying to loop through an array that contains other arrays and these arrays consist of strings with spaces. The problem is that I can't seem to preserve the spacing in the string. The string with spaces are either divided into multiple items if I change IFS to \n or all the elements of the array are seen as 1 item if I leave IFS unchanged here's some sample code:
#!/bin/sh
low1=("AA QQ" "BB LL")
low2=("CC" "DD")
low3=("EE" "FF")
high=(low1 low2 low3)
for high_item in ${high[@]}
do
eval arrayz=\${$high_item[@]}
#IFS=$'\n'
for item in $arrayz
do
echo $item
done
done
Output:
AA QQ BB LL CC DD EE FF
As you can see the elements "AA QQ" and "BB LL" have been split.
If I uncomment the line that sets IFS
to \n
I get the following:
AA QQ BB LL CC DD EE FF
Now "AA QQ" and "BB LL" are concatenated!
Is there anyway I can preserve these elements just as they original are...I need the output to look like that:
AA QQ BB LL CC DD EE FF
I think you meant that the output should look like:
AA QQ
BB LL
CC
DD
EE
FF
i.e.:
${low1[0]}
${low1[1]}
${low2[0]}
${low2[1]}
${low3[0]}
${low3[1]}
This could be accomplished using:
#!/bin/bash
low1=("AA QQ" "BB LL")
low2=("CC" "DD")
low3=("EE" "FF")
high=(low1 low2 low3)
for high_item in ${high[@]}
do
x="${high_item}[@]" # -> "low1[@]"
arrays=( "${!x}" )
#IFS=$'\n'
for item in "${arrays[@]}"
do
echo "$item"
done
done
And please always use #!/bin/bash
for bash scripts.
Explanation: ${!x}
is indirect variable expansion. It evaluates to the value of variable with a name contained in $x
.
For our needs, x
needs to have the [@]
suffix for array expansion as well. Especially note that it is x=${high_item}[@]
and not x=${high_item[@]}
.
And you have to evaluate it in array context; otherwise, it wouldn't work as expected (if you do arrays=${!x}
).
Ah, and as final note: IFS
doesn't make any difference here. As long as you are working on quoted arrays, IFS
doesn't come into play.
Replace eval
with indirect parameter expansion, and you'll get what I think you want (although it doesn't match your current given output:
for high_item in "${high[@]}"
do
arrayz="$high_item[@]"
# arrayz is just a string like "low1[@]"
for item in "${!arrayz}"
do
echo $item
done
done
Note the need to quote the array expansion in the inner loop to preserve the whitespace in elements of low1
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With