The UNIX and Linux Forums  
Hello and Welcome from United States to the UNIX and Linux Forums! Thank You for Visiting and Joining Our Global Community.

Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
.
google unix.com



Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts and shell scripting languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
mail function problem jwholey Shell Programming and Scripting 4 05-01-2008 12:21 PM
Script problem due to recursive directories Help please robertmcol Shell Programming and Scripting 2 04-27-2008 08:00 PM
Function Problem and CoreDump ZINGARO Shell Programming and Scripting 8 02-19-2008 06:37 PM
recursive function bebop1111116 High Level Programming 1 10-30-2006 08:12 PM
PERL function problem avadhani Shell Programming and Scripting 2 06-15-2005 05:18 AM

Closed Thread
English Japanese Spanish French German Portuguese Italian Dutch Swedish Russian Norwegian Hungarian Hebrew Danish Bulgarian Greek Powered by Powered by Google
 
LinkBack Thread Tools Search this Thread Rate Thread Display Modes
  #1 (permalink)  
Old 02-03-2007
malle malle is offline
Registered User
  
 

Join Date: Jan 2007
Location: Kolkata
Posts: 10
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
  #2 (permalink)  
Old 02-03-2007
zazzybob's Avatar
zazzybob zazzybob is offline Forum Advisor  
Registered Geek
  
 

Join Date: Dec 2003
Location: Melbourne, Australia
Posts: 2,100
Here's a simple starting point....
Code:
$ 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
  #3 (permalink)  
Old 02-03-2007
sb008 sb008 is offline Forum Advisor  
Registered User
  
 

Join Date: Jan 2007
Posts: 384
Quote:
Originally Posted by zazzybob
Here's a simple starting point....
Code:
$ 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.
  #4 (permalink)  
Old 02-03-2007
hegemaro hegemaro is offline
Registered User
  
 

Join Date: Feb 2006
Location: Schenectady, NY
Posts: 134
Arrow

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.
Code:
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,

Code:
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.

Code:
typeset FILENAME=/etc/hosts

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

echo $FILENAME
Function
echo $FILENAME
would produce
/etc/hosts
/etc/resolv.conf
/etc/hosts

Last edited by hegemaro; 02-03-2007 at 10:41 AM..
  #5 (permalink)  
Old 02-03-2007
malle malle is offline
Registered User
  
 

Join Date: Jan 2007
Location: Kolkata
Posts: 10
Thanks zazzybob. The solution was fantastic.

Thanks to everyone who has given some more hints about the solution.
Closed Thread

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -4. The time now is 09:04 AM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited. Language Translations Powered by .
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios
The UNIX and Linux Forums Content Copyright ©1993-2009. All Rights Reserved.Ad Management by RedTyger

Content Relevant URLs by vBSEO 3.2.0