Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have two drives with the same files, but the directory structure is totally different.

Is there any way to 'move' all the files on the destination side so that they match the structure of the source side? With a script perhaps?

For example, drive A has:
/foo/bar/123.txt
/foo/bar/234.txt
/foo/bar/dir/567.txt

Whereas drive B has:
/some/other/path/123.txt
/bar/doo2/wow/234.txt
/bar/doo/567.txt

The files in question are huge (800GB), so I don't want to re-copy them; I just want to sync the structure by creating the necessary directories and moving the files.

I was thinking of a recursive script that would find each source file on the destination, then move it to a matching directory, creating it if necessary. But that's beyond my abilities ...

Any help greatly appreciated!

Thanks

share|improve this question
    
Is this a one time script, or would this be something that you would need to do on an ongoing/recurring basis? –  Roy Rico Jan 25 '11 at 1:47
    
Are the filenames unique? That is, can you guarantee that there is only one file named "123.txt"? The answer to this question is the difference "quick and relatively easy" and "slow and somewhat more complex". –  larsks Jan 25 '11 at 1:53
    
If the file & folder structure is identical at some level, you should be able to use rync. –  martineau Jan 25 '11 at 5:22
    
@Roy -- I need this from time to time –  Ze'ev Jan 26 '11 at 4:08
    
@larsks - yes, the filenames are all unique. –  Ze'ev Jan 26 '11 at 4:09

1 Answer 1

up vote 2 down vote accepted

Given that your filenames are unique, this will work, albeit slowly:

#!/bin/sh

src=$1
tgt=$2

# Iterate over all the filenames in the source directory.
(cd $src && find . -type f -print) | while read src_path; do
    src_dir=$(dirname "$src_path")
    src_base=$(basename "$src_path")

    # find the file on the target with the same name.
    tgt_path=$(find $tgt -name "$src_base")

    # skip to next file if there's no matching filename
    # in the target directory.
    [ "$tgt_path" ] || continue

    # create the destination directory and move the file.
    mkdir -p "$tgt/$src_dir"
    mv "$tgt_path" "$tgt/$src_dir"
done

Note that (a) there's not much error checking going on here, (b) this will take a while if you have a lot of files, and (c) as written, this will probably leave a lot of empty directories in the target.

Here's my limited testing. With a source directory that looks like this:

$ find src -type f
src/b/file2.txt
src/a/file1.txt
src/c/file3.txt

And a target directory that looks like this:

$ find tgt -type f
tgt/file1.txt
tgt/file2.txt
tgt/not/the/right/place/file3.txt

If I have the above script in a file called reorg.sh and run it like this:

$ sh reorg.sh src tgt

I end up with a target directory that looks like this:

$ find tgt -type f
tgt/b/file2.txt
tgt/a/file1.txt
tgt/c/file3.txt
share|improve this answer
    
That looks like exactly whay I need! Thank you! –  Ze'ev Jan 27 '11 at 6:54

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.