I need to copy all files and directory from source let's say /var/www/html/test/ to destination /var/www/html/test2/. Destination can already have extra files and folders which i need to remove after copying the files from source.

I cannot delete everything from destination before copying it.


I tried following :

1) Copied the file from source to destination using cpcommand

cp -R source destination

which working fine.

2) I tried to iterate over all the files in destination file to check if the file is exist in source. If not remove the file from destination

for file in /var/www/html/test2/*; 
  do filestr=`basename $file`;echo $file; 
  if [ `ls /var/www/test1/ | grep -c $filestr` -eq 0 ]; 
 then rm $file; fi; 

which working fine for the root files in the destination only.

Need to find out how to recursively check all file and directory matching with source or not.

  • I adjusted my answer, try it out.
    – Ziazis
    Commented Jul 13, 2017 at 7:38

2 Answers 2


This is a classic use case for rsync. rsync will copy a directory tree from source to destination. It can also be asked to delete excess other files after the copy:

rsync -a -v --delete-after /var/www/html/test/ /var/www/html/test2  

Note the trailing / on the source specification. If you omit this, it'll copy the source directory itself, which you won't want.

If you want it to be quiet, remove the -v. If the files are large and compressible, you might want to try adding -z to get it to do compression and decompression, but I doubt it'll gain much. The --delete-after option deletes just the excess files and folders from the destination, but not until after the other files have been copied.

A bonus of using rsync is that it will not bother copying files that are the same (i.e. already there and that actually match).

  • Thank you for your answer. But rsync is not installed on server and we are not allowed to do so. Is this possible by running some shell commands? Commented Jul 12, 2017 at 9:10
  • It's complicated to do the deletion part. It's probably time you pressed management to install rsync!
    – Bob Eager
    Commented Jul 12, 2017 at 9:26
  • Maybe it's worth to try to just download your distributions rsync package, extract it and try to use it from your users folder.
    – Jaleks
    Commented Jul 12, 2017 at 21:35
  • 1
    The use of -z is certainly pretty useless for local copies. However, I haven't seen that documented anywhere. I have done local copies and accidentally used -z, and there has been a small 'speedup' according to the stats from -v.
    – Bob Eager
    Commented Jul 12, 2017 at 22:41
  • 1
    The problem with rsync is that it is designed to check if a file has been changed and then copy parts of it. This takes a lot of time. cp should be faster.
    – bomben
    Commented May 31, 2021 at 9:47



HITSDIR=`find $DESTINATION -type d | sed -e 's|'$DESTINATION'\(.*\)|\1|g'`

for i in $HITSDIR; do
if [ -e $SOURCE$i ]; then
echo Yes $SOURCE$i exists
echo Nope delete $DESTINATION$i.

HITSFILES=`find $DESTINATION -type f | sed -e 's|'$DESTINATION'\(.*\)|\1|g'`

for i in $HITSFILES; do
if [ -e $SOURCE$i ]; then
echo Yes $SOURCE$i exists
echo Nope delete $DESTINATION$i.

This should do what you want, just uncomment the rm once you did a dry run.

  • This will not delete the not existing files...
    – Jaleks
    Commented Jul 12, 2017 at 21:33
  • Ye, I adjusted it to his requirements.
    – Ziazis
    Commented Jul 13, 2017 at 7:37
  • Thank you very much @ziazis. This solution is working perfectly for me. You saved my day. Commented Jul 13, 2017 at 13:11
  • thanks a lot, this is perfect when working on stations that do not have rsync Commented May 5, 2023 at 10:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .