Array copy in ksh

Hi all,
Following code in ksh is giving error:

fileLimit=5
func(){
 dir="$1"
 format="$2"
 array="$3"
 i=0
 ls -lrt $format | tail -${fileLimit} | while read f_det; do
 files="${f_det},"
 ((i+=1))
 done
 eval $(echo set -A $array '"${files[@]}"')
}
 
func "." "*.pl" "a"
echo ${a[@]}

But if the line:

ls -lrt $format | tail -${fileLimit} | while read f_det; do

is changed to :

ls -lrt | while read f_det; do

it does not give any error...

any reason..?

what should be done the example to make it work..

Please help

Use code tag in your post to post the code.

PRKS, are those """s part of your shell script?

If we remove all """ and indenting for readability we are left with:

fileLimit=5
func ()
{
 dir="$1"
 format="$2"
 array="$3"
 i=0
 ls -lrt $format | tail -${fileLimit} | while read f_det
do
      files="${f_det}",
      ((i+=1))
done
eval $(echo set -A $array '${files[@]}')
}
 
func . "*.pl" a
echo ${a[@]}

Bearing in mind that I never use arrays and cannot verify that code. There is probably a spurious comma, but the main problem is that we are expanding ".pl" on the function call rather than within the function. Needs quotes until the point when you actually want to expand the "". Better to quote every text variable as good practice. There is also a space character missing on the function header (which might still work in some shells).

Because "ls -l" gives more than one field and more than one line (with tail -5) the best I can suggest is to put quotes round ${f_det}. I really don't know whether this will end up in the array. ... others will.

Btw. If you have further issues, please post what you typed, what you expected to happen, and what actually happened (including any error messages).

Original script...

---------- Post updated at 06:22 AM ---------- Previous update was at 06:19 AM ----------

fileLimit=5
func(){
        dir="$1"
        format="$2"
        array="$3"
        i=0
        ls -lrt | tail -5  | while read f_det; do
                files="${f_det},"
                ((i+=1))
        done
        eval $(echo set -A $array '"${files[@]}"')
}

func "." "*.pl" "a"
echo ${a[@]}

You did not say which version as ksh you were using. Assuming you are using ksh93, the following should work for you. It uses a nameref to avoid having to do an array copy.

#!/bin/ksh93

func()
{
    dir=$1
    format="$2"
    set -A $3
    nameref files=$3

    ls -lrt $format | tail -5 |
    while read f_det
    do
        files+=("${f_det},")
    done
}

func "." "*.pl" "a"
echo ${a[@]}

This gives for folowing output for me in a directory containig a number of .pl files

$ ./test.ksh
-rwxr-xr-x 1 fpm usr 427 Feb 7 2008 p6.pl, -rwxr-xr-x 1 fpm usr 136 Feb 7 2008 p7.pl, -rwxr-xr-x 1 fpm usr 215 Mar 22 20
08 p8.pl, -rwxr-xr-x 1 fpm usr 603 Mar 29 2008 p9.pl, -rwxr-xr-x 1 fpm usr 226 Mar 29 2008 p10.pl,

I am not sure why you want it in that particular format but good luck parsing it.

Hi...
ksh version in "Version 11/16/88"

Its giving this error...
try: Syntax error at line 11 : `(' is not expected.

You are using a very old version of ksh. The script I provided will not run on that version. What operating system are you using?

Hi fpmurphy,
I m using HP-UX.

All I want to do is to make a function that will store the list of files of a given directory (in an array perhaps) and return that array..

something like

listDir(){
...
...
return a; # a is an array
}

set -A arr1 $(listDir $dir1 $limit1)    #limit is the tail limit of ls -lrt
set -A arr2 $(listDir $dir2 $limit2)
set -A arr3 $(listDir $dir3 $limit3)

The return value of a function is a number, not a string.

One approach is to create your function (customise as you require) and pass the new array name to the function.

i.e.

$ cat ArrTest
GetDir() {
  cd $2
  ls -ltr | tail -$3 | while read FILE; do
    eval $1[\${#$1[@]}]="\$FILE"
  done
  cd - > /dev/null
}

# GetDir $1 is new array name, $2 is directory, $3 is the value for tail
GetDir A /tmp 5
echo A[0] is ${A[0]}
echo A[1] is ${A[1]}
echo
GetDir B /Users/scott 3
echo B[0] is ${B[0]}
echo B[1] is ${B[1]}


$ ./ArrTest
A[0] is drwx------ 3 scott wheel 102 5 Mar 20:49 launch-7Y8JI8
A[1] is drwx------ 3 scott wheel 102 5 Mar 20:49 launch-3RaSBo

B[0] is drwx------+ 79 scott staff 2686 26 Feb 20:54 Downloads
B[1] is drwxr-xr-x 34 scott staff 1156 5 Mar 00:33 scripts


The ksh in HP-UX 11.11 responds to "what" with vintage 11/16/88 (i.e. ksh88).
Not ksh93
Hope this helps.