Problem with Recursive function

Hi all,

I have to move all the files in a tree directory structure to a single directory. Inorder to know which file is from which directory , i'll have to add the name of the directory to the file name. For this i wrote a recursive function which is as follows
---------------------------------------------
datamover()
{
cd $1
#OLD_DIR=$2
for i in *
do
if [ -d $i ]
then
TMP_DIR=$i
datamover $TMP_DIR
echo $i
else
mv $i ../$1_$i

		if [ -f $1/ ]  
		then
		echo some files still exist
		else
		cd ..
		rmdir $1
		fi

	fi 
done 

}
----------------------------------------------------------------
When ever I execute the same on a directory structure as
DirA --> DirB --> DirL -->fileN
--> DirM-->fileO
--->DirC --> DirP-->fileR
--> DirQ-->fileS

the program is giving the output as follows
DirA -->DirB -->DirL_fileN
-->DirM_fileO
--->DirC --> DirP-->fileR
--> DirQ-->fileS

and the debug ouptut is as follows
------------------------------------------------------
+ echo Dir Name is DirA
Dir Name is DirA
+ MAIN_DIR=DirA
+ datamover DirA
+ cd DirA
+ '[' -d DirB ']'
+ TMP_DIR=DirB
+ datamover DirB
+ cd DirB
+ '[' -d DirL ']'
+ TMP_DIR=DirL
+ datamover DirL
+ cd DirL
+ '[' -d fileN ']'
+ mv fileN ../DirL_fileN
+ '[' -f DirL/ ']'
+ cd ..
+ rmdir DirL
+ echo fileN
fileN
+ '[' -d DirM ']'
+ TMP_DIR=DirM
+ datamover DirM
+ cd DirM
+ '[' -d fileO ']'
+ mv fileO ../DirM_fileO
+ '[' -f DirM/ ']'
+ cd ..
+ rmdir DirM
+ echo fileO
fileO
+ echo fileO
fileO
+ '[' -d DirC ']'
+ mv DirC ../DirA_DirC
mv: cannot stat `DirC': No such file or directory
+ '[' -f DirA/ ']'
+ cd ..
+ rmdir DirA
rmdir: `DirA': No such file or directory
--------------------------------------------------------------

Can anybody tell me wht's the problem with the code and how to correct it?
the output i require in this scenario will be as
DirA-->DirB_DirL_fileN
-->DirB_DirM_fileO
-->DirC_DirP_fileR
-->DirC_DirQ_fileS

Thanks in Advance

Here's a simple starting point....

$ find dirA -type f -print | while read filename; do
>    mv ${filename} ./destDir/`echo ${filename} | sed 's!/!_!g'`
> done
$ find dirA -type f -print
$ ls destDir
dirA_dirB_dirE_file_4  dirA_dirC_dirF_dirI_file_7  dirA_dirC_file_2       dirA_dirD_file_3
dirA_dirB_file_1       dirA_dirC_dirF_file_5       dirA_dirD_dirG_file_6

As you can see, all files are moved from dirA to destDir.

You can then just rm -rf dirA

Cheers
ZB

This is the way to do it.

The original script fails because of the
for i in *
statement

The * is evaluated at start of the function and doesn't anticipate on files moved to that directory from a subdirectory.

zazzybob's solution is an elegant and simple solution.

In response to recursion within a Korn shell function, there are two points to consider. All variables, including the current working directory, are global unless specifically defined with the function which then makes them local within the function.

typeset FILENAME=/etc/hosts

Function ()
{
    FILENAME=/etc/resolv.conf
    echo $FILENAME
}

echo $FILENAME
Function
echo $FILENAME

would produce

/etc/hosts
/etc/resolv.conf
/etc/resolv.conf

However,

typeset FILENAME=/etc/hosts

Function ()
{
    typeset FILENAME

    FILENAME=/etc/resolv.conf
    echo $FILENAME
}

echo $FILENAME
Function
echo $FILENAME

would produce
/etc/hosts
/etc/resolv.conf
/etc/hosts

A quick and dirty way to make variables local to the function INCLUDING the working directory is to execute the function in its own shell by placing parenthesis within the function brackets. The function will get its own copy of the environment when called and any changes, including the directory, to that environment will not be reflected in the calling script which is its own function.

typeset FILENAME=/etc/hosts

Function ()
{ (
    FILENAME=/resolv.conf
    echo $FILENAME
) }

echo $FILENAME
Function
echo $FILENAME

would produce
/etc/hosts
/etc/resolv.conf
/etc/hosts

Thanks zazzybob. The solution was fantastic.
:slight_smile:
Thanks to everyone who has given some more hints about the solution.