Reputation: 387
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
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
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