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

2
  • 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
    Commented Sep 15, 2022 at 21:10
  • 2
    if test "$dir" != "${dir// /_}"; then mv "${dir}" "${dir// /_}"; fi Commented Sep 15, 2022 at 21:12

2 Answers 2

2

Simply replace

for dir in */

with

for dir in *\ */

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

2
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)
1

Not the answer you're looking for? Browse other questions tagged or ask your own question.