See http://mywiki.wooledge.org/BashFAQ/001 for what you're doing wrong. You have to be careful about using the output of a command with spaces in it, to make sure you don't use it in a context where it will be word-split.
In your specific example, you don't actually need a regex. Shell glob expressions will do the trick.
for i in [0-9][0-9]' -'*; do
mv "$i" "${i// /_}"; # / at start of pattern = all matches.
done
Or more usefully for messing around with filenames:
- prename (perl-based renamer, packaged in Debian/Ubuntu in the
perl package)
mmv 'foo*.mp3' 'bar#1.mp3'
So your goal of replacing track numbers with Eagles would be:
prename 's/[0-9]+ -/Eagles -/' *.mp3
Or tack Eagles - onto the front of every filename.
prename 's/^/Eagles - /' [0-9]*.mp3 # or:
prename '$_ = "Eagles - " . $_' [0-9]*.mp3 # you aren't limited to the s// operator, it really does eval as perl code.
Notice how you can use shell globs to select files to run prename on, so your actual pattern doen't have to avoid matching filenames you can filter other ways. If you want to use / in your pattern (to move files to a subdirectory, for example), I suggest using s{pat}{repl} syntax. So much nicer than a sed one-liner that turns into a forest of \/.
There's a shopt -s extglob bash option, but you're probably better off just using regexes instead of that, unless you're writing shell scripts for max efficiency. (e.g. programmable completion functions that run every time someone presses tab).