Problem accessing array elements

Hi all,
I can�t resolve an array element access issue on (Linux/pdksh) .. So I�m positing for advice.By the way - a friend demonstrated to me - same script works as expected under Solaris.

I have been working on a documentation project where many *.jpg screen shots are used in the documentation. The process that we go through - has us inserting additional images into the sequence of JPG files (where required). Eventually the sequence of images is �frozen� before they go into the next phase of the documentation process.

We need to have these images renumbered before the sequence is frozen. So for example we might start with:
Image_1

Image_34 With the additional insertions (and deletions too) � the directory structure morphs into something ugly like:
Image_1
Image_1a
Image_1b
Image_9
Image_9c
Image_9f
Image_34
Image_34h
We need to have a script process the directory structure and sort / rename these files into something like Image_0000, Image_0005, image_00010, image_0015, etc. (incremented by 5�s).

Having 5 spaces (between files) allows us to insert images into the sequence � if we should need to in a last minute emergency effort during later stages of the documentation process.

The problem:

The script is giving us problems (on linux). I can load the array in a loop � but I can NOT access the array elements outside of the loop and I am looking for advice on how to resolve this issue on the Linux box.

Please note - The same script works on Solaris as expected � array elements are accessible outside of the loop!!! (We cant use the Solaris box for this process).

Thank you for your time and input on this matter - Dave

#!/bin/ksh

touch /tmp/1.jpg /tmp/23.jpg /tmp/65.jpg /tmp/88.jpg

i=0
ls -alF /tmp/*.[jJ][pP][gG] | awk '{print $8}' | while read filein
do
   array[$i]=$filein
   echo "in loop: i=$i, Array($i)='s: ${array[$i]}"
   i=$(($i + 1))
done

echo "out of loop - 2nd element: ${array[2]}"
echo "out of loop - all elements: ${array[@]}"

rm /tmp/1.jpg /tmp/23.jpg /tmp/65.jpg /tmp/88.jpg

This is a useless use of ls *:

ls -alF /tmp/*.[jJ][pP][gG] | awk '{print $8}' | while read filein

You can strip out a ls, a read, and an awk by just doing this instead:
Since you're globbing anyway, why not just do:

for filein in /tmp/*.[jJ][pP][gG]

The pipe chain was causing your array problems because, in many shells, that entire loop behind the pipes will be executed inside a separate subshell.

isn't there a setting in ksh, similar to bash's "shopt -s nocaseglob" to enable case insensitive globbing?

also pdksh is not maintained anymore.
you might like to try mksh
MirOS: mksh ? the MirBSD Korn Shell

my tip:
when you start resorting to arrays in shell scripts maybe you are using the wrong tool.

Corona688:thank you - your advice worked nicely... That web page was rather informative (bookmarked that one).

Kurumi:RE: that entire loop behind the pipes will be executed inside a separate subshell.

yes that's what I was thinking when I saw the array data in the loop - but not external to the loop.
Bigearsbilly:I was not aware of the status of pdksh (I'll be moving the ubuntu systems over to mksh I guess). I installed mksh on my ubuntu 11.04 (beta) machine and tested again - same error. I still would have changed / optimized the line - but wanted to see if mksh would handle the issue differently.

RE: when you start resorting to arrays in shell scripts maybe you are using the wrong tool.

Yeah - I generally avoid arrays in ksh, and was thinking about moving over to perl... But:

  • I knew I was doing something blatantly wrong - and a simple fix was probably not too far away.
  • The use of the array was the right way to handle this simple task.
  • Others in the group have agreed to use/support ksh in the environment. So using perl for this one simple task, seemed a bit excessive for what we wanted to do.

All: Thanks for your time on this matter!