4

I am trying to write a bash script that will go through a directory and rename the files (the file name is really crazy and is not recognizable to any human as what they are) to "Chapter1.mp3", "Chapter2.mp3", etc, but when I do this, I get the following error:

mv: target 'Chapter##.mp3' is not a directory

As I recall, the mv command allows you to specify a filename as well as a directory... why am I getting this error? The following is my code:

cptr=0;

for i in ./myFolder/*; do
    cptr=$(($cptr+1)); # I can't remember, can I use cptr++?
    mv -v $i "Chapter$cptr.mp3";
done;

I've tried removing the file extension, removing the quotes, even using the cp command instead, but nothing I have tried has worked.  Why is it requiring the target to only be a directory and not a filename?

I am using the Ubuntu 20.04 LTS terminal with Linux Subsystem for Linux; does this make any difference?

2 Answers 2

11

If you have any filenames with spaces (or tabs or newlines) in them, then you need to put $i in quotes.  If, for example, your 42nd file is named foo bar, then

mv -v $i "Chapter$cptr.mp3"

will be expanded as

mv -v ./myFolder/foo bar "Chapter42.mp3"

which looks like you’re running mv with three name arguments.  Running mv with three or more name arguments is valid only if the last name is a directory (e.g., mv *.mp3 my_music).  Since you do not have directories named ChapterNN.mp3, you get the error you reported.

So do

mv -v "$i" "Chapter$cptr.mp3"

I said “If you have any filenames with spaces … in them, then you need to put $i in quotes.”  Of course I meant “You should put $i in quotes, so your script will work if you ever have any filenames with spaces … in them.”

0

Note: This answer can work, but it is not a good solution. Please see the comments below and the answer that I have selected as the solution, it is a much better solution than mine.


I was doing

for i in ./my\ folder/*; do
    ...
done;

instead of

for i in ./my_folder/*; do
    ...
done;

For some reason it wasn't liking the spaces even though I had the backslash, to escape the space, and so it was messing things up. I just renamed the folders with no spaces, and then it worked fine.

6
  • 1
    -1. Adjusting input data to flawed script is wrong. Fixing the script so it can handle any data is right. Commented Jan 16, 2022 at 9:37
  • 2
    Scott has the right answer. Variable references should almost always be in double-quotes, to avoid problems like this. shellcheck.net will spot this and many other common scripting mistakes; I recommend running all your scripts through it and fixing what it points out. Commented Jan 16, 2022 at 10:24
  • Yes, thank you! It's been a while since I took a class on bash scripting. Now that you pointed out putting double quotes around variables, I remember my teacher saying it was best practice, and that (like you said) it would solve these kinds of problems before they even happen. Commented Jan 16, 2022 at 17:17
  • @gordon thank you for that tool! I will definitely bookmark it for future use. Commented Jan 16, 2022 at 17:18
  • I edited my answer telling people to look at your comments and the other answer, because mine is not a good solution. Thank you for your input. Commented Jan 16, 2022 at 17:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .