Take the 2-minute tour ×
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.

I'm trying to move the following move a large number of files that exist in the following structure to a /mnt/originals but I need to maintain the structure at the same time. I know cp would be a solution but can't use cp because of space limitations.

/mnt/originals-us/4
/mnt/originals.us/4/0b9
/mnt/originals.us/4/0b8
/mnt/originals.us/4/0b4
/mnt/originals.us/4/0b3
/mnt/originals.us/4/0b9/a62/
/mnt/originals.us/4/0b9/a47/
/mnt/originals.us/4/0b9/f0f/
/mnt/originals.us/4/0b9/a62/aa5/file16.png
/mnt/originals.us/4/0b9/a62/ba1/file1.png
/mnt/originals.us/4/0b9/a47/31f/file3.mov
/mnt/originals.us/4/0b9/f0f/
.
.
.

Etc. It is a pretty large set of files of different file names and types. I tried the following but it didn't work.

mv /mnt/originals-us/ /mnt/originals/ 

but get the following

mv: inter-device move failed: `/mnt/originals-us/10/0b9/' to `/mnt/originals/10/0b9'; unable to remove target: Is a directory

I also thought about writing a massively chanin-ed command but I don't think that would work either.

This is what I have so far.

find . -type f -print | rev | cut -d '/' -f1 | rev

This obviously gives me all the filenames but how do I chain it with the first part?

share|improve this question

2 Answers 2

up vote 5 down vote accepted

One option would be to use rsync with --remove-source-files

rsync -vr --remove-source-files /mnt/originals-us/ /mnt/originals/

Potential caveat: I do not know how rsync checks for space before performing potentially damaging actions. In a perfect world, rsync would calculate how much space is needed, check to see if that is available, then abort and warn the user or (if the space is adequate) perform the operation.

EDIT: I omitted the recursion option (-r) by mistake, thanks to the OP for mentioning, now fixed

share|improve this answer
    
Worked perfectly after I added -r so it should be rsync -v -r --remove-source-files /mnt/originals-us/ /mnt/originals/ –  Mark D Feb 21 at 17:06
1  
@MarkD I recommend -a (preserve everything), which includes -r as well as preservation of permissions, timestamps, special files, etc. –  Gilles Feb 21 at 23:43

The rsync solution is a lot more efficient but it is possible with find, too. The worst case: one process per file:

find ... -exec cp --parents {} /dest/path \; -delete

find would delete the source file after successful copy only.

But we can start a project "fun with find" for optimization (remove the echos and the \ before the | after testing):

find ... -type d -exec echo mkdir /target/{} \; -exec bash -c \
  'echo find {} -maxdepth 1 -type f -print0 \| '\
  'xargs -0 mv --target-directory=/target/{}' \;

In the typical case: 5 processes per directory.

With your example (few files per directory) it may make sense to make a -print0 | xargs -0 mkdir in the target root first (and take the mkdir out of the main find call).

share|improve this answer
    
I really like the solution but you're right rsync was more efficient. –  Mark D Feb 21 at 17:32

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.