Kei Nivky
Kei Nivky

Reputation: 387

simple bash script to change spaces to underlines in a file name

mv $1 $(echo $1 | sed s:\ :_:g)

It's a simple script that renames the file passed as argument, exchanging spaces to underlines. However, when I try to rename the file "a e i" to "a_e_i" for example, it returns the following error:

./spc2und a\ e\ i 
mv: target `a_e_i' is not a directory

Upvotes: 1

Views: 2869

Answers (3)

Gordon Davisson
Gordon Davisson

Reputation: 126098

You need double-quotes around the variables and command substitution to prevent spaces in the filename from being mistaken for argument separators. Also, you don't need sed, since bash can do character replacement by itself:

mv "$1" "${1// /_}"

Edit: a few more things occurred to me. First, you really should use mv -i in case there's already a file with underscores ("a_e_i" or whatever). Second, this only works on simple filenames -- if you give it a file path with spaces in an enclosing directory, (e.g. "foo bar/baz quux/a e i"), it tries to rename it into a directory with the spaces converted, which doesn't exist, leading to comedy. So here's a proposed better version:

mv -i "$1" "$(dirname "$1")/$(basename "${1// /_}")"

BTW, the other answers leave off the double-quotes on the filename after replacing spaces with underscores -- this isn't entirely safe, as there are other funny characters that might still cause trouble. Rule 1: when in doubt, wrap it in double-quotes for safety. Rule 2: be in doubt.

Upvotes: 7

Frank Schmitt
Frank Schmitt

Reputation: 30845

Your $1 expands to a e i, which is then used as the first three arguments to mv, so your call becomes

mv a e i a_e_i

This is the reason for the error message you get. To fix this, all you have to do is quote the $1:

mv "$1" $(echo "$1" | sed s:\ :_:g)

Upvotes: 2

clt60
clt60

Reputation: 63974

try this - pure bash:

mv "$1" ${1// /_}

Upvotes: 5

Related Questions