Total beginner here, trying to write some code to remove first space from a batch of file names.

When I type in terminal:


for f in *.jpg; do echo mv "$f" “${f/ /}”; done

I get:

mv R 1  Pe.jpg “R1 Pe.jpg”
mv R 10 Ma.jpg “R10 Ma.jpg”
mv R 11 An.jpg “R11 An.jpg”

But when I remove echo, the actual renaming does not happen, I get this error:

for f in *.jpg; do mv "$f" “${f/ /}”; done
usage: mv [-f | -i | -n] [-v] source target
       mv [-f | -i | -n] [-v] source ... directory
usage: mv [-f | -i | -n] [-v] source target
       mv [-f | -i | -n] [-v] source ... directory
usage: mv [-f | -i | -n] [-v] source target
       mv [-f | -i | -n] [-v] source ... directory

Any suggestions?

  • Note there is no limit to the number of characters after the ., therefore you can name your files *.jpeg. Not even Microsoft's OSes have this limit: not since 1995. – ctrl-alt-delor Apr 2 '20 at 20:19

Those aren't quotes. You have not ":

$ uniprops “
    \pP \p{Pi}
    All Any Assigned Punct Is_Punctuation Common Zyyy Pi P General_Punctuation
       InPunctuation Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase
       Initial_Punctuation Pat_Syn Pattern_Syntax PatSyn Print X_POSIX_Print
       Punctuation QMark Quotation_Mark Unicode X_POSIX_Punct

$ uniprops '"'
    \pP \p{Po}
    All Any ASCII Assigned Basic_Latin Punct Is_Punctuation Common Zyyy Po P
       Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Other_Punctuation
       Pat_Syn Pattern_Syntax PatSyn POSIX_Graph POSIX_Print POSIX_Punct Print
       X_POSIX_Print Punctuation QMark Quotation_Mark Unicode X_POSIX_Punct

Since the quotes in the target names are not proper double quotes, the second argument would be split on spaces, and the first mv command would try to move the two files R 1 Pe.jpg and “R1 to non-existing directory Pe.jpg”. This is what causes the errors.

So try this:

for f in *.jpg; do echo mv "$f" "${f/ /}"; done
  • That works perfectly, thanks for pointing out the obvious mistake. Noted the difference between ASCI and Unicode. – Jaume Insa Apr 3 '20 at 6:01

Yes it is a quoting problem (see other answers).

However for this specific problem, it is better done with the rename command. (The one by Larry Wall)


rename -n -e "s/ //" *.jpg

After testing, and checking the output. Remove the -n.


On Debian with apt install rename.


Yes, the quotes are an issue. The echo shows the command as:
mv R 1 Pe.jpg “R1 Pe.jpg”
If you were to type this onto the command line, it would fail, because the spaces in the source are neither quoted nor escaped. The correct command would be:
mv "R 1 Pe.jpg" "R1 Pe.jpg"
To put quites around the $f variable, I would suggest something like this:
mv "\""$f"\"" "${f/ /}"
where the "\"" is the escape code to print a double quote.
To wit: echo " n " displays n. echo " \n " escapes the n and shows a newline. Similarly, echo " \" " escapes a quote inside quotes.
Another option qould be:
mv '"'$f'"' "${f/ /}"

  • Why would you add two layers of quotes around $f? And echo "\n" won't print a newline in any echo implementation I know of. Some would with echo -e "\n". The OP's command was fine, they just weren't using ASCI quotes but instead had fancy unicode. – terdon Apr 2 '20 at 20:58
  • Disagree. The first argument of the mv command contains spaces. It will not work as intended. the first arg should be EITHER: "R 1 Pe.jpg" -or- R\ 1\ Pe.jpg. Otherwise, the mv command has 4 arguments: Arg1 R arg2 1 arg3 Pe.jpg arg4 R1\ Pe.jpg – Scottie H Apr 2 '20 at 22:23
  • @terndon It is also possible that the Unicode quotes were simple a translation issue from the original source into the test window. Is it even possible you to easily put Unicode quotes into your script while using a text editor? – Scottie H Apr 2 '20 at 22:28
  • @terndon, I have had echo "Line 1\nLine 2" work without the -e. And, don't be dumb, clearly it is just an example for level of understanding. – Scottie H Apr 2 '20 at 22:29
  • 1
    @terdon, dash and zsh process backslashes in echo by default. And well, the standard leaves it implementation defined. – ilkkachu Apr 3 '20 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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