简体   繁体   中英

perform a function on each element in an array in ksh

I have a variable from a previous portion of my script that is greped/sed/cut/sort/uniq from many lines of a previous script output into exactly what i need, n amount of numeric data

echo "$array"
12345
54321
01234

it is my understanding I can treat this column of numbers as an array

the number of items can vary from only 1 to maybe as many as 6. I have verified there is no whitespace that may be throwing things off.

from here i attempt to

for element in "{array[@]}"; do

foo $anothervar "$element"

bar $anothervar "$element"

done

but i end up with all the values in the variable.

foo $anothervar 12345 54321 01234

(please note, $anothervar is just for demonstration purposes, it is actually $1 and so shell expansion of that var isn't necessarily the problem)

and so on. if I

#with double quotes
echo "$element"
12345
54321
01234

#without quotes
echo $element
12345 54321 01234

so I can't do iterative anything with this data. Am I incorrect that I can treat this variable as an array and must perform another action to the var before I can input it to the for loop?

what I am hoping for

foo $anothervar "$element"
*output of $anothervar 12345*

bar $anothervar "$element"
*output of $anothervar 12345*

foo $anothervar "$element"
*output of $anothervar 54321*

bar $anothervar "$element"
*output of $anothervar 54321*

etc etc

This is ksh88 on AIX, from what I have researched this should work, unless possibly ksh88 vs later versions may be involved? I am new to arrays but not new to shell scripting, though I would hardly call myself expert. Thanks in advance for any help provided.

I don't have a ksh88 available for experimentation but with ksh93 (I am using Version AJM 93u+ 2012-08-01 ) this will produce something like your data:

$ val=` for ((ii=1; ii<4; ii++))
do
echo $ii
done`

If I echo this the two different ways, I get what you see to start:

$ echo $val
1 2 3
$ echo "$val"
1
2
3

Now, I add a function

$ function foo {
> echo $1 $2
> }

I can loop through the values, one aa time with:

$ for xx in $val
> do
> foo foo $xx
> done
foo 1
foo 2
foo 3

Or all together (which is not what you want):

$ for xx in "$val"
> do
> foo foo $xx
> done
foo 1

Hey, what happened to the rest of my values? Look closely, by adding the quotes around $val , we are assigning all values to xx at once. We can see this more clearly with:

for xx in "$val"
do
foo foo $xx
echo "The value of xx=$xx"
echo "or in hex:"
echo "The value of xx=$xx" | xxd -g 1
done
foo 1
The value of xx=1
2
3
or in hex:
0000000: 54 68 65 20 76 61 6c 75 65 20 6f 66 20 78 78 3d  The value of xx=
0000010: 31 0a 32 0a 33 0a                                1.2.3.

the single value of xx is 1\n2\n3\n (\n is newline) and when we pass it to the foo function, it only sees the first value, 1.

If we updated this slightly,

for xx in "$val"
do
foo foo "$xx"
done
foo 1 2 3

we see the separate values were passed to the function. Since the function is not quoting the $2 argument, we don't see the newlines.

Does that answer your question?

I recommend using ksh93 since you don't want to be 27 years behind the times. David Korn updated ksh rather substantially, starting in 1993 and the updates are worth the extra effort of typing ksh93 rather than just ksh on AIX.

Which are you using, var=... or array=(... ... ...) or?? Edit your Q to show acompletely testable set of data, along with your required output/actions (yes you are close). I would try for elem in ${var[@]}; do...` (no dbl-quotes). Good luck.

thank you @ shellter, the double quotes were indeed the issue. I assume, since I found that in a previous answer here that it must be valid syntax for a later version of ksh but for today you solved my issue and I appreciate all who provided suggestions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM