First, reconstruct the directory tree of the source in the destination:
cd source
find -type d -exec mkdir -p destination/{} \;
The {} in the find should contain the relative path of each directory.
Then, check if the directory tree you created in the destination looks good. And try to move each file individually:
cd source
find -type f -exec mv {} destination/{} \;
I can't tell you enough how potentially dangerous this is. You could lose data! I am not sure what find is going to do if it can't stat a file. My hope is that it will just emit a message error and move on. But since you are apparently trying to recover data from a damage medium, you're probably aware of any risks.
If this works as intended, all that will be left in the source are the directories and the files that couldn't be moved. If you want, you can search on SO how to remove the empty directories recursively (I'm 100% sure this has been asked before) to make your analysis easier.
I suggest you make a small test case in the damaged medium. mkdir a few directories, touch some random files and try these steps to see what happens. Also probably a good idea if you do this in one directory a time instead of doing it in the root.
What I mean is, if your strucutre is, for example:
.
├── dir1
│ ├── fileA
│ └── subdir1
│ └── fileB
├── dir2
│ └── fileC
└── dir3
├── subdir1
│ └── fileD
└── subdir2
└── fileE
Then run it 3 times; once in dir1, then if everything runs smooth, move to dir2, and dir3, instead of doing everything at once at ..