bash error renaming files with spaces - mv target is not a directory bash error renaming files with spaces - mv target is not a directory bash bash

bash error renaming files with spaces - mv target is not a directory


Try:

for f in *.txt; do mv "$f" "${f// /}"; done

Three points:

  1. The quotes around a shell variable should not be escaped.

  2. In general, it is a good idea to put double-quotes around every reference to a shell variable.

  3. ${f/ /} removes just the first occurrence of a space. To remove all spaces, use ${f// /}.

What went wrong

$ touch {a,b}" .txt"$ ls *.txta .txt  b .txt$ for f in *.txt; do mv \"$f\" ${f/ /}; donemv: target `a.txt' is not a directorymv: target `b.txt' is not a directory

The expression \"$f\" does not behave like it is double quoted. It expands to two arguments, such as "a and .txt", where the double-quotes are treated as normal characters, just like the a is a normal character. Because there are three arguments to mv ("a and .txt" and a.txt), mv believes that you are trying to move the first two arguments to the third and the third is required to be a directory. Since the third is not a directory, it issues an error message.


Because this is the first thing that came up on google when googling this error, I thought I'd add a bit.

This error occurs if you have more than two arguments and the last result is not a directory.

This works (when output.txt does not exist):

mv file1.txt output.txt

This does not (if file2.txt does exist):

mv file1.txt file2.txt

In my case I was doing: mv prefix_* output_file_name to ensure a downloaded file had a consistant name, but another file had appeared in the directory, restulting in the "mv target is not a directory" error