I wrote a script today as follows:
echo "Enter a directory path"
read dir
for file in $dir/[!.]*;
do
f=`echo $file | sed 's/ /_/g'`
mv "${file}" "${f}"
done
Initially, the mv command was written as:
mv ${file} ${f}
But that line was throwing
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
I was able to use google to figure out that the variables needed to be wrapped in double quotes, but I still don't understand why doing so resolved the problem?
Thanks!
Quoting, in shell, prevents string-splitting and glob expansion. If you don't double-quote your variables, you have no idea how many arguments each variable may expand into after these parsing steps are run.
That is:
mv $foo $bar
...may turn into...
mv ./first word second word third word destination-file
if
foo='./first word second word third word'
bar='destination-file'
Similarly, consider the case where you have a filename containing a glob expression:
foo='hello * world'
In that case, your mv
command would get a list of all files in the current directory.
...or, consider the case when an argument is empty:
foo='hello world'
bar=''
In this case, instead of (properly) getting an error that you can't have file with a 0-byte name, you would be trying to rename a file named hello
to world
: The $bar
simply disappears.