# Question on iterating array elements

**URL:** <https://community.unix.com/t/question-on-iterating-array-elements/352703>\
**Category:** Shell Programming and Scripting\
**Created:** [May 15, 2015, 8:25am UTC](https://community.unix.com/t/question-on-iterating-array-elements/352703 "2015-05-15T08:25:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![newbie\_01](https://community.unix.com/letter_avatar/newbie_01/32/5_5575768a8748004e209b776fc1b2916d.png) [@newbie\_01](https://community.unix.com/u/newbie_01)\
**Post date:** [May 15, 2015, 8:25am UTC](https://community.unix.com/t/question-on-iterating-array-elements/352703/1 "2015-05-15T08:25:52Z")

</div>

Hi,

I am trying to do something similar to the for loop example from [KSH For Loop Array: Iterate Through Array Values](http://www.cyberciti.biz/faq/ksh-array-iteration-examples-using-for-loop/)

```plaintext
$: cat y.ksh
#!/bin/ksh
# set array called nameservers
set -A nameservers 192.168.1.1 192.168.1.5 202.54.1.5

# print all name servers
for i in ${nameservers[@]}
do
        echo $i
done
$: ./y.ksh
192.168.1.1
192.168.1.5
202.54.1.5

```

My test script looks like below:

```plaintext
#!/bin/ksh
#
#

set -A arrSID
set -A arrVERSION

arrVERSION[1]="Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production"
arrVERSION[2]="Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production"

echo
echo
for i in ${arrVERSION[@]}
do
   echo $i
done
echo
echo

```

It's output when I run it is as below:

```plaintext
$: ./x.ksh

Oracle
Database
11g
Enterprise
Edition
Release
11.2.0.4.0
-
64bit
Production
Oracle9i
Enterprise
Edition
Release
9.2.0.8.0
-
64bit
Production

```

I managed to use the while loop below and manage to get the output that I wanted.

```plaintext
$: ./z.ksh
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
$: cat z.ksh
#!/bin/ksh
#
#

set -A arrSID
set -A arrVERSION

arrVERSION[1]="Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production"
arrVERSION[2]="Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production"

i=1
while [[$i -le ${#arrVERSION[@]} ]]
do
   echo ${arrVERSION[$i]}
   (( i=i+1 ))
done

exit 0

```

I just want to know why the for loop, i.e. the x.ksh, does not work like I expect it to be? I am guessing it is due to the spaces in the string. Is there any way around it. I just thought it is easier to use the for loop instead of the while loop.

Anyway, any feedback much appreciated. Thanks.

---

<div class="post-metadata">

**Author:** ![CarloM](https://community.unix.com/letter_avatar/carlom/32/5_5575768a8748004e209b776fc1b2916d.png) [@CarloM](https://community.unix.com/u/CarloM)\
**Post date:** [May 15, 2015, 8:46am UTC](https://community.unix.com/t/question-on-iterating-array-elements/352703/2 "2015-05-15T08:46:40Z")

</div>

You could use the array indices in the for loop:

```nohighlight
for i in ${!arrVERSION[*]}
do
   echo "${arrVERSION[$i]}"
done

```

---

<div class="post-metadata">

**Author:** ![RudiC](https://community.unix.com/letter_avatar/rudic/32/5_5575768a8748004e209b776fc1b2916d.png) [@RudiC](https://community.unix.com/u/RudiC)\
**Post date:** [May 15, 2015, 9:03am UTC](https://community.unix.com/t/question-on-iterating-array-elements/352703/3 "2015-05-15T09:03:46Z")

</div>

Try quoting:

```nohighlight
for i in "${arrVERSION[@]}"
  do echo $i
  done

```

---

<div class="post-metadata">

**Author:** ![bakunin](https://community.unix.com/letter_avatar/bakunin/32/5_5575768a8748004e209b776fc1b2916d.png) [@bakunin](https://community.unix.com/u/bakunin)\
**Post date:** [May 15, 2015, 9:35am UTC](https://community.unix.com/t/question-on-iterating-array-elements/352703/4 "2015-05-15T09:35:23Z")

</div>

> [@newbie\_01](#):
>
> I just want to know why the for loop, i.e. the x.ksh, does not work like I expect it to be?

The construct "${array[@]}" expands to all elements of this array. Note that also the construct "${array[_]}" is expanded to all the array elements. The difference of these seemingly identical constructs is the used separating character. "${arr[@]}" uses an IFS character, "${arr[_]}" does not.

You will not see a difference in the following call:

```plaintext
arr[1]="one two three"
arr[2]="four five six"

print - "-------- Using the asterisk:"
for i in ${arr[*]} ; do
     print - $i
done

print - "-------- Using the ampersand:"
for i in ${arr[@]} ; do
     print - $i
done

# ./arrtest.sh:
-------- Using the asterisk:
one
two
three
four
five
six
-------- Using the asterisk:
one
two
three
four
five
six

```

But once you quote properly (notice the double quotes around the variables to be expanded):

```plaintext
arr[1]="one two three"
arr[2]="four five six"

print - "-------- Using the asterisk:"
for i in "${arr[*]}" ; do
     print - $i
done

print - "-------- Using the asterisk:"
for i in "${arr[@]}" ; do
     print - $i
done

# ./arrtest.sh 
-------- Using the asterisk:
one two three four five six
-------- Using the asterisk:
one two three
four five six

```

The reason i sthe way the shell parses its input: in a first step all the variables are expanded, So from the line

```plaintext
for i in "${arr[@]}" ; do

```

The shell creates:

```plaintext
for i in "one two three[IFS-char]four five six" ; do

```

In a second step this is fed to the (internal) "for"-command, which evaluates this again. At this point " " (blank) and "[IFS]" (which, per default, is a blank too) have no difference and therefore get mixed up: this is why the first example produced each word on a separate line. Once you protect this line (by quoting it) from the shells interpretation it gets read correctly - at least with the "@" because the "\*" now has another (and in your case equally unintended) meaning.

I hope this helps.

bakunin
