Use this with bash
:
find $1 -name "* *.xml" -type f -print0 | \
while read -d $'\0' f; do mv -v "$f" "${f// /_}"; done
find
will search for files with a space in the name. The filenames will be printed with a nullbyte (-print0
) as delimiter to also cope with special filenames.
Then the read
builtin reads the filenames delimited by the nullbyte and finally mv
replaces the spaces with an underscore.
EDIT: If you want to remove the spaces in the directories too, it's a bit more complicated. The directories are renamed and then not anymore accessible by the name find
finds. Try this:
find -name "* *" -print0 | sort -rz | \
while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done
The sort -rz
reverses the file order, so that the deepest files in a folder are the first to move and the folder itself will be the last one. So, there are never folders renamed before all files and folder are rename inside of it. The mv
command in the loop is a bit changed too. In the target name, we only remove the spaces in the basename of the file, else it wouldn't be accessible.