Bash scripts tend to use transformation programs that accept input through standard input and use the output from standard output. For replacing one character with another, the "tr" program is typically used.
To operate on the command-line arguments to a program like "mv", bash allows you to use back-tick quotes.
set FNAME="path/bad:file\\name"
mv "$FNAME" `echo "$FNAME" | tr ":\\" "_-"`
Note the use of escaped backslashes... the pair represents a single charcter. Be sure to study the manual for each command (e.g. man tr
) before using it at first.
Te experiment building this kind of complicated command, replace the "mv" with "echo" to see what the two constucted arguments will be, and switch back to "mv" when they look right.
One approach to looping is to turn the above into a script that fixes one filename specified as an argument to the script ($1 inside the script) and then interactively pipe all the filenames through xargs to give them one at a time to your script.
find topdir -type f | xargs -d "\n" yourscriptname
You must try this on sample data and also backup your current data before turning your script loose on it... so often there are little things that don't behave the way you expect when some unexpected input interacts with your script.
Finally, there are scripting languages like Python that have a lot of these capabilities built in... and with more consistent syntax than the many-tools bash approach, but they can have the headache of a lot more specialized setup requirements than just bash to go along with those advantages.