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?
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 filesI'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
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~
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.