9

I want to update some forum software and I'd like to test the upgrade process using CLI as a learning possibility.

How do I merge contents of a folder into another folder and replace files?

10

You can use rsync to do this:

$ rsync -abviuzP src/ dest/
  • -a archive mode; equals -rlptgoD (no -H,-A,-X)
  • -i turns on the itemized format, which shows more information than the default format
  • -b makes rsync backup files that exist in both folders, appending ~ to the old file. You can control this suffix with --suffix .suf
  • -u makes rsync transfer skip files which are newer in dest than in src
  • -z turns on compression, which is useful when transferring easily-compressible files over slow links
  • -P turns on --partial and --progress
    • --partial makes rsync keep partially transferred files if the transfer is interrupted
    • --progress shows a progress bar for each transfer, useful if you transfer big files

I'd drop several of these switches but this is just to get you started. I'd probably use something like this:

$ rsync -abuP src/ dest/

Once it looks OK, you can run this command to remove the backup files:

$ find dest/ -name "*.~" -delete

Example

Let's pretend that we have the following sample data.

original data

We'll use the following commands to manufacture some fake data.

$ seq 10 | xargs -I{} -- mkdir dest/dir{}
$ for i in $(seq 5); do echo "$i" > dest/dir$i/file$i;done

Fake data looks as follows:

$ tree -DsifvF --noreport dest/
dest
[       4096 Aug 29 22:21]  dest/dir1/
[          2 Aug 29 22:21]  dest/dir1/file1
[       4096 Aug 29 22:21]  dest/dir2/
[          2 Aug 29 22:21]  dest/dir2/file2
[       4096 Aug 29 22:21]  dest/dir3/
[          2 Aug 29 22:21]  dest/dir3/file3
[       4096 Aug 29 22:21]  dest/dir4/
[          2 Aug 29 22:21]  dest/dir4/file4
[       4096 Aug 29 22:21]  dest/dir5/
[          2 Aug 29 22:21]  dest/dir5/file5

new data

Now we'll replicate the original data (dest/* -> src/) and the add a couple of newer files to the mix. This simulates a "new release.

$ cp -pr dest/* src/
$ mkdir src/dir11
$ for i in 1 3 5 11; do echo "$i$i" > src/dir$i/file$i;done

Fake data looks as follows:

$ tree -DsifvF --noreport src/
src
[       4096 Aug 29 22:21]  src/dir1/
[          3 Aug 29 23:00]  src/dir1/file1
[       4096 Aug 29 22:21]  src/dir2/
[          2 Aug 29 22:21]  src/dir2/file2
[       4096 Aug 29 22:21]  src/dir3/
[          3 Aug 29 23:00]  src/dir3/file3
[       4096 Aug 29 22:21]  src/dir4/
[          2 Aug 29 22:21]  src/dir4/file4
[       4096 Aug 29 22:21]  src/dir5/
[          3 Aug 29 23:00]  src/dir5/file5
[       4096 Aug 29 23:00]  src/dir11/
[          5 Aug 29 23:00]  src/dir11/file11

merge src/ into dest/

This mimics that we just setup our new software tree in src/ and want to merge into our pre-existing directory, dest/.

$ rsync -abuP src/ dest/
sending incremental file list
dir1/file1
           3 100%    0.00kB/s    0:00:00 (xfer#1, to-check=5/13)
dir11/
dir11/file11
           5 100%    4.88kB/s    0:00:00 (xfer#2, to-check=4/13)
dir3/file3
           3 100%    2.93kB/s    0:00:00 (xfer#3, to-check=2/13)
dir5/file5
           3 100%    2.93kB/s    0:00:00 (xfer#4, to-check=0/13)

sent 416 bytes  received 97 bytes  1026.00 bytes/sec
total size is 18  speedup is 0.04

As you can see the following files were updated, file1, file3, file5, and the newly added dir11 + file11.

And as confirmation we can see that the following backup files were created by rsync when it encountered the pre-existing files in dest/.

$ find dest/ | grep "~"
dest/dir3/file3~
dest/dir1/file1~
dest/dir5/file5~
  • To clarify the point above: Once it looks OK, you can run this command to remove the backup files: > $ find dest/ -name "start dot ~" -delete This didn't seem to work for me, whereas: > $ find dest/ -name "start dot star ~" -delete did. Not sure if that's a typo or something not set up right my end! – user90104 Nov 3 '14 at 12:22
2

You can use cp -r name_of_the_folder/* name_of_the_destination_folder where the asterisk(*) stands for all files and -r for recursive copy.

You can use also the -i option which will ask you if you want to overwrite the contents.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.