$: 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:
#!/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:
$: ./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.
$: ./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.
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:
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):
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
for i in "${arr[@]}" ; do
The shell creates:
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.