Shell Noob

Hi all,

I am trying to write a shell script that will move files from one directory to another, the only thing is I want to to check loads of different source directory and move the files to loads of different directories.

I am totally new to shell scripts but not to UNIX (although I would still class myself as a newbie).

Any advice would be welcome, as I am sat looking at a rather empty page in vi and goggling like crazy but not coming up with much.

You are kinda vague. If you need to move a whole tree try something like this:

cd /path/to/upper/level/of/source
tar -cvf - $(find . -print -type f) | (cd ../destination ; tar -xvf -)

find gets all of the files in the source tree, feeds the file to tar, the tar on the other end of the pipe then parks the file in a new directory tree with the same subdirectories. This is not deleting anything. This is a VERY general solution -

Ok, being new to this I have drawn a pic to help me explain......

ok hopefully this will help me explain what I'm trying to do.

I did ls | wc -l on /user and that gave 392, which sounds about right (give or take 15 random other directories and files that are in there).

So I am trying to move files from one private folder (under xxxx.old) to the other private folder, I need to do this somewhere in the region of 350 times on different folders.

Apologies for my naff explanation but hopefully my wonderful picture will give you a clue what I'm on about :wink:

Sax,
See if this works for you.
Note that I commented the "cp" (copy) statement so that you can
make sure it does what you want first, before running it.

for mNewDir in `find /user/ -type d -name 'accu*'`
do
  mNewBase=`basename ${mNewDir}`
  mNewPriv=${mNewDir}"/private/"
  mOldPriv="/user/dotolds/"${mNewBase}".old/private/"
  echo "Now copying from "${mOldPriv}" to "${mNewPriv}
  #####cp ${mOldPriv} ${mNewPriv}
done

Cheers, looks like just what i'm after, however I am getting a syntax error on line 5 (syntax error at line 5: `mNewPriv=$' unexpected), the only thing I have changed is the find (see below).

I have been through I a couple of time to check what I have typed in vi matches your solution, and I am sure I have typed it correctly.

for mNewDir in `find /user/ -type d -name 'accu*.old'`
do
  mNewBase=`basename ${mNewDir}`
  mNewPriv=${mNewDir}"/private/"
  mOldPriv="/user/dotolds/"${mNewBase}".old/private/"
  echo "Now copying from "${mOldPriv}" to "${mNewPriv}
  #####cp ${mOldPriv} ${mNewPriv}
done

Sax,
The "find" statement is to loop through all the "accuNNN" directories,
NOT the "accu*old".
Display the "mNewDir" right after the "do" to see what value you are getting:

echo "mNewDir = <"${mNewDir}">"

Also, I wrote the shell in ksh -- are you using the same?

I think I see how it's working now.
I changed the find back, and changed the script to ksh. I also added the line above.
When I run it I don't get any errors, but then I don't get anything else ? I left the copy command commented out and ran it, but I didn't get any output, I thought I would at least see the echo lines :confused:

Sax,
You should see the output of:

echo "Now copying from "${mOldPriv}" to "${mNewPriv}

Verify that your find command returns somme output.

Jean-Pierre.

The find command works, but how would I stop it going too deep ? some of the directorys have other files and directorys in them that match accu*.

Sax,
You can change the "for" statement as follows:

for mNewDir in accu*

I have made that change.

what is the best way to test this script, I have run it with the copy command commented out, but I haven't seen any output to the screen ??

Ebable the trace :

  1. Execute the find command to verify that it returns a list a files
    text find /user/ -type d -name 'accu*.old'
  2. Enable the trace
    text set -x for mNewDir in `find /user/ -type d -name 'accu*.old'` do mNewBase=`basename ${mNewDir}` mNewPriv=${mNewDir}"/private/" mOldPriv="/user/dotolds/"${mNewBase}".old/private/" echo "Now copying from "${mOldPriv}" to "${mNewPriv} #####cp ${mOldPriv} ${mNewPriv} done

Jean-Pierre.

Ebable the trace :

  1. Execute the find command to verify that it returns a list a files
    text find /user/ -type d -name 'accu*.old'


    the find command works...
  2. Enable the trace
    text set -x for mNewDir in `find /user/ -type d -name 'accu*.old'` do mNewBase=`basename ${mNewDir}` mNewPriv=${mNewDir}"/private/" mOldPriv="/user/dotolds/"${mNewBase}".old/private/" echo "Now copying from "${mOldPriv}" to "${mNewPriv} #####cp ${mOldPriv} ${mNewPriv} done

I added set -x to the script and when I ran it, it printed the find command but nothing after that.

Cheers for the tip on the set command, thats a keeper :wink:

The code seems to be correct, i doesn't see why it is not working fine.
You can try to replace the for command by a while loop, but there is no reason that the result be better :

set -x
find /user/ -type d -name 'accu*.old' | \
while read mNewDir
do
  mNewBase=`basename ${mNewDir}`
  mNewPriv=${mNewDir}"/private/"
  mOldPriv="/user/dotolds/"${mNewBase}".old/private/"
  echo "Now copying from "${mOldPriv}" to "${mNewPriv}
  #####cp ${mOldPriv} ${mNewPriv}
done

Jean-Pierre.

set -x
find /user/ -type d -name 'accu*.old' | \
while read mNewDir
do
  mNewBase=`basename ${mNewDir} .old`
  mNewPriv=${mNewBase}"/private/"
  mOldPriv="/user/dotolds/"${mNewBase}".old/private/"
  echo "Now copying from "${mOldPriv}" to "${mNewPriv}
  #####cp ${mOldPriv} ${mNewPriv}
done

In blue?

Ok guys, I have made all the changes suggested and run the script..

I saw the expected output however there was loads of not founds ?

Unfortunately due to time constraint and other work, I have decided to tar up the dotold dir and archive it to a backup, if the user miss any data I'll just have to restore.

Don't worry though, I still have loads of scripting projects in the pipeline.

Thanks for all your help, just this simple exercise has taught me loads. I am keeping the script and might try to finish it off when work calms down.

Thanks again

Sax