Tricky array substitution in functions


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Tricky array substitution in functions
# 1  
Old 11-06-2008
Tricky array substitution in functions

Hello,

Please tell me if there is a better way to get the number of elements from an array that is passed to a function.

This is what works on Solaris 8 (ksh) but it looks odd:

Code:
loop_array() {

array_name=$2

        b1='\${\#'
        b2='[@]}'

        nr_elements=`eval echo $b1$array_name$b2`
        # this one prints the actual variable I want to reassign ...
        echo $nr_elements
        # it seems to only work like this
          nr_elements=`eval echo $nr_elements`
          echo $nr_elements
        # this line prints out the number of elements correctly but when I assign it to a variable with ` ` I get bad substitution error
        eval echo \${\#$array_name[@]}

#...
}

Thanks

Last edited by majormark; 11-07-2008 at 03:11 AM..
# 2  
Old 11-06-2008
I guess the 'last' acctualy is the 'nr_elements' or you have something missed.

If it is, let see what the 'last' has:

You have build correct string "\${\#$array_name[@]}"; asked to 'eval'uate it - have in result "${#<arr_name>[@]}"; and asking to execute it!
Try execute this line with correct array name: you will have :command not found!
Because it will produce a number of the array elements and a number is not a command by itself.

I did not clear understand what do you need: the correct number of element for any given array or the command itself into a variable?

If the array element number, you do not need to escape the characters in b1 and b2 (acctualy, I do not see why do you need them) :
Code:
b1='${#';
b2='[@]}'
eval echo $b1$array_name$b2

I do not see any reason to build a command itself and after that execute it. It will required double execution, as you already figured it out.

So, you have an array name in a variable and would like to call a function that returns the aray elements number? A function need to be executed to get a result. So:
Code:
>elms(){ eval echo \${\#$1[@]\}; return 0;}

># - checking:
>a1=(aa dd cc rr);
>a2=(klkl ioio opo);
> echo `elms a1`
4
> echo $(elms a2)
3

To get just a "echo $nr_elements" the nr_elements should be a variable, which you could set in a function. So
Code:
>set_elms_n(){ elm_n=$(eval echo \${\#$1[@]\}); return 0;}
>set_elms_n a1
>echo $elm_n;
4
>set_elms_n a2
>echo $elm_n;
3

That what you was looking for?

Last edited by alex_5161; 11-06-2008 at 02:24 PM..
# 3  
Old 11-07-2008
This is partially what I wanted, thank you for the tips.

What I need is to use the variable inside the function itself not outside.

For example:
Code:
set_elms_n(){ elm_n=$(eval echo \${\#$1[@]\}); echo $elem_n; return 0;}

# when I run "set_elms_n a1" I get no result.

The rest of the function continues with a loop through the array backwards(decrementing the number of lines variable), so that is why I need the variable to be set inside the function.
# 4  
Old 11-07-2008
Smilie
- you just misspell variable in function!
Code:
> set_elms_n(){ elm_n=$(eval echo \${\#$1[@]\}); echo $elm_n; return 0;}
> set_elms_n a1
4

# 5  
Old 11-07-2008
try this as well:
Code:
# pass arrays by value not by "reference"
trn_arr()
{
   
   set -A arr $1
   echo "array length= ${#arr[*]}"
   pos=$2
   pos=$(( pos -1 ))
   echo " $2 element of array = ${arr[pos]}"
}

set -A myarr 9 8 7 6 5 4 3 2 1
trn_arr "${myarr[*]}"  4

# 6  
Old 11-07-2008
It is oversimlified.
Also the array is redefined (acctually, it is where the problem set):
Code:
> a11=("1-two words" 2-jkjk 3-uiuiu 4-opopop 5-tytyty)
> ec ${#a11[@]}
5
> trn_arr "${a11[*]}"  2
array length= 6
 2 element of array = words
>

# 7  
Old 11-12-2008
Just recall this last pointed by Jim try to send an array by value, instead of by reference (in shell - just the name.)
The point is that it could be done in correct way, but with appropriate call syntaxis:
Code:
>
> arr=("two words" "one" "more")
>
> prt_arr(){ 
> n_el=$#;        # number of positional parameters could be the same as in arr
>                   # the positional parameters are array, acctualy; 
>                   # no needs to re-assign
>                   # could be accesed with simplified way: $1, $2, .. that is 
>                   # the same, as ${arr[0]}, ${arr[1]}, ...
> while [[ ! -z $* ]]; 
>   do /usr/bin/echo "$1\n"; 
>   shift; 
> done; 
> echo "orig number : $n_el";}
>
>    # now it is important to call in correct way: with @ and in ""
> prt_arr "${arr[@]}"
two words

one

more

orig number : 3
>
>    # other way call does not produce expected result:
> prt_arr ${arr[@]}
two

words

one

more

orig number : 4
> prt_arr ${arr[*]}
two

words

one

more

orig number : 4
> prt_arr "${arr[*]}"
two words one more

orig number : 1
>

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

Code review: recursion in circular array, reduce two functions to one?

Hello, I think there's an easier way to do this but can't seem to recall but given an array of animals and an initial value is a random index in the array, here it's 3. 3,4,5,4,3,2,1,0,1,2,3,4,5,4,3,2,1,0... inifinite repeat a quick brute force solution i came up with was two functions, i... (6 Replies)
Discussion started by: f77hack
6 Replies

2. Shell Programming and Scripting

Need help with array substitution

Hello all, I have following piece of code which is working fine if executed standalone - date=$1 set -A max_month 0 31 28 31 30 31 30 31 31 30 31 30 31 eval $(echo $date|sed 's!\(....\)\(..\)\(..\)!year=\1;month=\2;day=\3!') (( year4=year%4 )) (( year100=year%100 )) (( year400=year%400 ))... (7 Replies)
Discussion started by: ektubbe
7 Replies

3. Shell Programming and Scripting

Variable substitution in array printing

Hi folks, A really dumb question as I've wasted far too long trying to get this to work.... (on RH bash) I have an array: m0='<hello>' m0='<there>' m0='<fred>' v0='<goodbye>' v0='<again>' v0='<john>' in my code I calculate the value of the variable to output and if I echo it, I... (2 Replies)
Discussion started by: say170
2 Replies

4. Shell Programming and Scripting

Need help on Assigning a Array variable from Background Functions

I have a question on how can I assign a output of a function to a variable which is executed in background. Here is my example $ cat sample_program.sh #!/bin/ksh exec_func () { sleep 1 v=`expr $1 + 100` print $v } export OUT_ARR date for i in 1 2 do OUT_ARR=`exec_func $i` &... (1 Reply)
Discussion started by: mohan_kumarcs
1 Replies

5. Shell Programming and Scripting

How to execute functions or initiate functions as command line parameters for below requirement?

I have 7 functions those need to be executed as command line inputs, I tried with below code it’s not executing function. If I run the ./script 2 then fun2 should execute , how to initiate that function I tried case and if else also, how to initiate function from command line if then... (8 Replies)
Discussion started by: saku
8 Replies

6. Shell Programming and Scripting

Substitution in a file dont work with an Array in filename

Hi. I´ve a script that should substitude the 8th line in a file called xxx.num6. The "xxx" is set by an array filled with this command: j=0 for Par in *.sys ; do Par=`echo $Par | sed 's/\(.*\).sys/\1/'` ; Par2="$Par" ; echo "${Par2}" j=$((j + 1)); done Now i try... (0 Replies)
Discussion started by: Lock3
0 Replies

7. Shell Programming and Scripting

Passing array to functions in ksh script

Let me know if there is a way to pass array to a funtion in ksh script. function isPresent { typeset member member=$1 dbList=$2 echo '$1:' $1 echo '$2' $dbList The array will be at the second position....something like this isPresent 12 <array> if then echo... (3 Replies)
Discussion started by: prasperl
3 Replies

8. Shell Programming and Scripting

Array reference - bad substitution

I've created a series of arrays named as follows: row1 row2 row3 . . . row10 Each has 4 elements. I'm trying to echo the array elements out in a for loop. Here's what I have: for ((i=1;i<=10;i++)) do for ((j=1;j<=4;j++)) do eval out=${row`echo $i`} echo -n $out (3 Replies)
Discussion started by: swankgd
3 Replies

9. Programming

[ C ] multidemensional array pass to functions

Please excuse my ineptitude for a bit as I've been spoiled for the past few months with only writing perl code instead of C. So ok, I've been thinking about some code to change the crc32 values that are held within central directory headers of zip files. Because I'm lazy I decided to just... (3 Replies)
Discussion started by: VRoemer
3 Replies

10. Shell Programming and Scripting

Array help (variable substitution).

I am using an array (clmlist01). I have 61 of these and have 4 or more references to each one in a block of code that I do not want to have to hardcode. With that being said, I am creating a varible and going through a for loop to create the actually name of each array. The arrays would end up... (3 Replies)
Discussion started by: dsimpg1
3 Replies
Login or Register to Ask a Question