Problem
Can someone offer a safe way to replace spaces in file and directory names starting from a specific root directory with underscores in a recursive manner? Consider the following scenario:
$ tree
.
|-- a dir
| `-- file with spaces.txt
`-- b dir
|-- another file with spaces.txt
`-- yet another file with spaces.pdf
becomes:
$ tree
.
|-- a_dir
| `-- file_with_spaces.txt
`-- b_dir
|-- another_file_with_spaces.txt
`-- yet_another_file_with_spaces.pdf
Asked by armandino
Solution #1
I use:
for f in *\ *; do mv "$f" "${f// /_}"; done
It’s not recursive, but it’s quick and simple. Someone here could probably make it recursive.
The $f/ / section of the command uses bash’s parameter expansion mechanism to replace a pattern within a parameter with a string given by the user. $parameter/pattern/string is the correct syntax. See http://wiki.bash-hackers.org/syntax/pe or https://www.gnu.org/software/bash/manual/html node/Shell-Parameter-Expansion.html.
Answered by Naidim
Solution #2
Use rename (also known as prename), a Perl script that may already be installed on your system. It should be done in two steps:
find . -name "* *" -type d | rename 's/ /_/g' # do the directories first
find . -name "* *" -type f | rename 's/ /_/g'
Using the “Revision 1.5 1998/12/18 16:16:31 rmb1” version of /usr/bin/rename (a Perl script) and Jürgen’s solution, I was able to handle many levels of files and directories in a single bound:
find /tmp/ -depth -name "* *" -execdir rename 's/ /_/g' "{}" \;
Answered by Dennis Williamson
Solution #3
find . -depth -name '* *' \
| while IFS= read -r f ; do mv -i "$f" "$(dirname "$f")/$(basename "$f"|tr ' ' _)" ; done
I initially failed to get it correctly since I didn’t consider directories.
Answered by Michael Krelin – hacker
Solution #4
Doug Harple’s cleanse can be used.
detox -r <folder>
Answered by user78274
Solution #5
A rename/find solution. rename is a util-linux command.
Because a whitespace filename can be part of a whitespace directory, you must descend depth first:
find /tmp/ -depth -name "* *" -execdir rename " " "_" "{}" ";"
Answered by Jürgen Hötzel
Post is based on https://stackoverflow.com/questions/2709458/how-to-replace-spaces-in-file-names-using-a-bash-script