Option 1: go back in time and read this: http://lincolnloop.com/blog/2012/jan/6/detecting-file-moves-renames-rsync/
This uses a trick with hardlinks to optimise the operation (note carefully the omission of trailing "/" in the example though, that might be different to what you are used to). If you have a local backup copy prior to the reorg, you can perhaps restore and use that (the complication is being able to create the hardlink copy as required).
Option 2: if you have no spaces/quotes in your file or directory names, and do not intend keeping any duplicates, you can create a quick and dirty copy/rename script like this.
find . -type f | xargs sha1sum | sort > /tmp/src.out
find . -type f | xargs sha1sum | sort > /tmp/dst.out
dst.out file over to source, and then on source do:
join -j 1 /tmp/src.out /tmp/dst.out | while read sum src dst; do
if [ "$src" != "$dst" ]; then
echo mkdir -p $(dirname "$src")
echo cp -ipl "$dst" "$src"
done > fixup.sh
This will output a set of
mkdir/cp commands that you can run (
fixup.sh) in the top directory of your copy on the destination. Make sure that the script output will do what you require it to do.
cp -ipl will not overwrite without prompting, and will copy by hard-linking. A subsequent
rsync --delete ... will delete the old files, assuming that want an identical copy. Use
rsync --dry-run ... afterwards to confirm the extent of any remaining differences.
(It is possible to use "
mv -i" instead of the non-destructive "
cp -ipl", saving the duplication and cleanup.)
If you have problematic file/directory names, you'll need to do some intermediate processing of filenames, or try one of the solutions here: http://unix.stackexchange.com/questions/6411/any-way-to-sync-directory-structure-when-the-files-are-already-on-both-sides
If you can tolerate the explosion-in-a-punctuation-factory that passes for a
sed command line:
find . -type f -print0 | xargs -0 sha1sum |
sed -re $'s/(^[0-9a-z]*) /\\1__/;
s/ /\\\\x20/g; s/\'/\\\\\'/g;
s/ (.*)$/ $\'\\1\'/g;'
This will handle spaces and single/double quotes (though we're approaching
perl territory for proper heavy lifting). It uses the bash
$'' construction for quoting troublesome strings.