0

On Bash, I used the following script to replace the empty spaces in some directories with an underscore:

for dir in */; do
mv "${dir}" "${dir// /_}"
done

This did the trick but still received unnecessary output for directories that did not have an empty space to be replaced:

mv: cannot move 'directory1' to a subdirectory of itself, 'directory1/directory1'

Is there a more succinct way to carry this out in bash that doesn't result in a message for each of those directories that was unaffected?

Thanks

dubg
  • 21
  • 8
  • 1
    You could start with a `find` expression that would produce a list of directories that contain one or more spaces in their name, and see where that takes you. Or just stick an `if` statement in your existing loop... – larsks Sep 15 '22 at 21:10
  • 2
    `if test "$dir" != "${dir// /_}"; then mv "${dir}" "${dir// /_}"; fi` – William Pursell Sep 15 '22 at 21:12

2 Answers2

2

Simply replace

for dir in */

with

for dir in *\ */

You may also consider setting nullglob option (shopt -s nullglob) before the for loop.

M. Nejat Aydin
  • 9,597
  • 1
  • 7
  • 17
  • 1
    FWIW, matching only source names containing the character we want to rename is covered in the duplicate at https://stackoverflow.com/a/2710485/14122 – Charles Duffy Sep 15 '22 at 22:42
  • https://stackoverflow.com/a/18213120/14122 is a nonrecursive version, thus basically identical to this answer (except a bit more comprehensive, as it doesn't elide the `mv` itself). – Charles Duffy Sep 15 '22 at 22:43
0

You may like to consider using a command line tool designed for this kind of task. Two I regularly use are rename and detox.

$ mkdir -p 'foo bar/bar foo'
$ rename --nono --fullpath 's/\s+/_/' *
rename(foo bar, foo_bar)
$ detox --dry-run *
foo bar -> foo_bar
foo bar/bar foo -> foo bar/bar_foo

Note that rename is not recursive whereas detox is. Rename is a perl program so you can use PCRE regexes.

If you need to recurse with rename you can do the following:

$ shopt -s globstar
$ rename --nono --fullpath 's/\s+/_/' **
rename(foo bar, foo_bar)
rename(foo bar/bar foo, foo_bar/bar foo)
htaccess
  • 2,800
  • 26
  • 31
  • Both `rename` and `detox` are already covered by answers in [the very longstanding duplicate](https://stackoverflow.com/questions/2709458/how-to-replace-spaces-in-file-names-using-a-bash-script). – Charles Duffy Sep 15 '22 at 22:42