Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

If I use mv to move a folder called "folder" to a directory that already contains "folder" will they merge or will it be replaced?

share|improve this question
up vote 49 down vote accepted

mv cannot merge or overwrite directories, it will fail with the message "mv: cannot move 'a' to 'b': Directory not empty", even when you're using the --force option.

You can however use rsync with the --remove-source-files option (and possibly others) to merge one directory into another.
rsync won't delete any directories, so you will have to do something like find -type d -empty -delete afterwards to get rid of the empty source directory tree.

share|improve this answer
    
It sounds like you've tried just one implementation of mv. This answer would be better with a broader truth. Linux, BSD and "real" Unix, or a reference from POSIX or SUS. – Warren Young May 3 '14 at 19:29
    
@WarrenYoung You're right, I only tried the mv implementation used by Debian - the emphasis being on tried, since the manpage doesn't mention this behavior... – n.st May 3 '14 at 23:47
13  
The disadvantage of rsync is that it actually copies the data, rather than just changing the hard link, which is potentially resource intensive if you're dealing with a lot of data. – Jonathan Mayer Sep 13 '14 at 18:53
rsync -av /source/ /destination/
(after checking)
rm -rf /source/
share|improve this answer
    
Will this remove the source files like in the comment by n.st? – Dominique May 3 '14 at 19:01
2  
No, I would prefer to make it in two steps for safety reasons. Merged and removed source is unreversible. Additon step in n.st anwer is also needed (to remove directories). – fazie May 3 '14 at 19:10
2  
--remove-source-files has the advantage of only removing files that were transferred successfully, so you can use find to remove empty directories and will be left with everything that wasn't transferred without having to check rsyncs output. – n.st May 3 '14 at 23:51
    
But it is not moving actually - the speed impact is huge, if big files are involved. – Alex Mar 15 at 15:12
    
But you cannot perform pure move and merging actually. – fazie Mar 15 at 19:58

I'd recommend these four steps:

cd ${SOURCE}; 
find . -type d -exec mkdir -p ${DEST}/\{} \; 
find . -type f -exec mv \{} ${DEST}/\{} \; 
find . -type d -empty -delete

or better yet, here's a script that implements semantics similar to mv:

#!/bin/bash

DEST="${@:${#@}}"
ABS_DEST="$(cd "$(dirname "$DEST")"; pwd)/$(basename "$DEST")"

for SRC in ${@:1:$((${#@} -1))}; do   (
    cd "$SRC";
    find . -type d -exec mkdir -p "${ABS_DEST}"/\{} \;
    find . -type f -exec mv \{} "${ABS_DEST}"/\{} \;
    find . -type d -empty -delete
) done
share|improve this answer
    
Args are SOURCE, DEST – schuess Jan 4 at 14:32

Here is a way that will merge the directories. It is much faster than rsync since it just renames the files instead of copying them and then deleting them.

cd source; find -type f -print0 | xargs -0 -n 1 -I {} mv '{}' 'dest/{}'
share|improve this answer
    
That's interesting but only vaguely relevant to the topic and not even remotely what the user asked about. – Shadur Sep 5 '14 at 5:14
12  
Actually, Jewel's code does precisely what the user asked for, with the exception of creating missing directories. Perhaps you should look again? – Jonathan Mayer Sep 13 '14 at 18:44
1  
I would add to use "-print0" in find and "-0" in xargs because there are files that have spaces in the names. Also, there is a small problem, if a name contains parenthesis they are not going to be moved. – markuz Aug 18 '15 at 16:33
    
This is much faster than rsync for a small number of files, but it forks a new process for every file, thus the performance is abysmal with a large number of small files. @palswim's answer does not suffer from this problem. – b0fh Mar 1 at 14:43

You can use the -l option of the cp command, which creates hard links of files on the same filesystem instead of full-data copies. The following command copies the folder source/folder to a parent folder (destination) which already contains a directory with the name folder.

cp -rl source/folder destination
rm -r source/folder

You may also want to use the -P (--no-dereference - do not de-reference symbolic links) or -a (--archive - preserve all metadata, also includes -P option), depending on your needs.

share|improve this answer
    
Hard links for what excuse ? – rautamiekka Feb 13 at 17:54
    
@rautamiekka: I assume you are asking the reason for using hard links. If you don't know what hard links are and why you should use them, then you probably shouldn't take this route. However, creating hard links does not do a full copy, so this operation would take orders of magnitude less time than a full copy. And, you would use hard links rather than soft links so that you can delete the source files and still have the correct data instead of pointers to invalid paths. And cp rather than rsync since every system has cp and everyone has familiarity with it. – palswim Feb 16 at 18:24

One way to accomplish this would be to use:

mv folder/* directory/folder/
rmdir folder

As long as no two files have the same name in folder and directory/folder, you will achieve the same result i.e. merging.

share|improve this answer
3  
How exactly does rm folder work? – JakeGould May 4 '14 at 4:28
3  
@JakeGould Not at all. :) – n.st May 4 '14 at 6:58
    
rm folder -fR always works for me – Octopus Dec 10 '15 at 2:43
    
Be aware that this will not work for hidden files – b0fh Mar 1 at 14:20

Here is a script that worked for me. I prefer mv over rsync, so I use Jewel and Jonathan Mayer's solutions.

#!/bin/bash

# usage source1 .. sourceN dest

length=$(($#-1))
sources=${@:1:$length}
DEST=$(readlink -f ${!#})
for SRC in $sources; do
    pushd $SRC;
    find . -type d -exec mkdir -p ${DEST}/{} \;
    find . -type f -exec mv {} ${DEST}/{} \;
    find . -type d -empty -delete
    popd
done
share|improve this answer
    
This solution does not properly escape path names, be careful. – user12439 Jun 7 '15 at 5:15
    
@user12439, I'll update the solution if you show me which part to fix. – xer0x Jun 8 '15 at 22:53

It is not a good idea to use commands like cp or rsync. For large files, it will take a long time. mv is much faster since it only update the inodes without copying the files physically. A better option is to use the file manager of your operating system. For Opensuse, there is a file manager called Konquerer. It can move files without actually copying them. It has "cut and paste" function like in Windows. Just select all the sub-directories in directory A. Right click and "move into" directory B which may contain sub-directories with the same names. It will merge them. There are also options whether you want to overwrite or rename files with the same name.

share|improve this answer
1  
OP asks what happens when mv is used. – don_crissti Feb 26 at 13:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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