A simple script incorporting the following should suffice:
There are any number of ways to suck up the filenames, e.g.
filelist=(find ~/whatever)
With zsh, you can do recursive globbing, usnig a **.
filelist=(~/whatever/**)
but don't try that in bash!
Once you have your list of filenames, they just need
a little massaging,
Take a filename:
foo=/some/path/a/b/c/d.e
With zsh, you can nest parameter expansions, but bash can't,
as far as I know, so I'll seperate them:
First, strip off the leading path name, using ${...#...}
foo=${foo#*/some/path/}
(don't forget the trailing slash). This will leave you with "a/b/c/d.e"
Now replace each / with an _, using a ${...//...} expansion (rtfm
foo=${foo//\//_}
foo is now, of course, "a_b_c_d.e". Voila!
Now just mv/cp/ln the original filename to $foo.