Recursively move directories along with files/specific files

I would like to transfer all files ending with .log from /tmp and to /tmp/archive (using find )
The directory structure looks like :-

/tmp
    a.log
    b.log
    c.log
         /abcd
             d.log
             e.log

When I tried the following command , it movies all the log files to /tmp/archive (does not maintain the directory structure )

find /tmp -name "*.log" -type f -exec mv {} /tmp/archive \; 

The output is

/tmp/archive
     a.log
     b.log
     c.log
     d.log
     e.log

whereas the output should be

/tmp/archive
     a.log
     b.log
     c.log
          /abcd
             d.log
             e.log

For copying (cp) ,this can be done using -R but does not work with move (mv) .Is there any simple command to achieve this .

I had gone through forums and come across few commands rsync ,tar ......

find /tmp -name "*.log" -type f -exec rsync {} /tmp/archive \;   /* gives the same output */

Also , could anyone explain the difference between cp and rsync
What is the usage of the command tar?

Try:

cd /tmp;find . -name "*.log" | xargs -i bash -c "echo {} | cpio -pdmu /tmp/arc; rm -f {}"
1 Like

Bartus11,
could you please explain the code ?

Bartus ,
I did understand the first part of the command
Could you also please explain the later part of the command ,
xargs -i bash -c "echo {} | cpio -pdmu /tmp/arc; rm -f {}" What is the usage of xargs , bash , cpio -pdmu

Is there any other suggestions ?

First tell us if it worked in your case :). xargs is passing the output from find as "{}". It is then used in bash command to execute two utilities: cpio and rm. cpio copies the file with its subdirectories if necessary (-d cpio option), while rm removes the original file after it has been copied.

What Operating System and version do you have?

uname -a

What Shell do you use?

echo $SHELL

On a design point, is this a one-off exercise or a job which will be run more than once? There are real scripting issues with your archive directory /tmp/archive being under /tmp .
Also on most unix systems /tmp is of limited size and considered volatile storage for files used by the Operating System. It is usual to create separate filesystems for application data and logs.

Sorry Bartus , It didnt work

Here is one other example which I have tried

/* This is the structure for abcd*/

$ ls -R /usr/bin/abcd
/usr/bin/abcd:
efgh fff1.log fff2.log fff3.log

/usr/bin/abcd/efgh:
fff4.log fff5.log

/* I am creating another directory called abcd1*/

$ mkdir /usr/bin/abcd1

/* Using your command , I am moving the *.log files from abcd to abcd1 ,including the directory structure ( sub directories ). As you can see , it fails with the output below */

$ find /usr/bin/abcd -name "*.log" | xargs -i bash -c "echo {} | cpio -pdmu /usr/bin/abcd1 ; rm -f {} "

0 blocks
0 blocks
0 blocks
0 blocks
0 blocks

if xargs is for passing the output then what is the usage -exec {} .Is there any difference between these two

---------- Post updated at 07:10 AM ---------- Previous update was at 07:02 AM ----------

Hi Methyl ,

The information you asked for

Operating System uname -a

Linux blrlx232n1 2.6.16.60-0.21-smp #1 SMP Tue May 6 12:41:02 UTC 2008 x86_64 x86_64 x86_64 GNU/Linux

echo $SHELL

/bin/ksh

Reference post #5. Did it fail? On the surface the code looks ok.
Just in case you have a weird system, what do you get for:

file /usr/bin/bash

Afterthought. You did create a shell script and execute that shell script rather than just typing the line at the command prompt?

Btw. Similar advice to before. I would avoid using system directories for application workspace. Messing with /usr/bin is not a good idea.

1 Like

Hi Methyl ,

The command works fine \( but I get 0 blocks on the screen \) . Also ,  I would like to know what would be the output if I dont use xargs in the command