2

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

8

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. 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. 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. Jan 16, 2022 at 17:17
  • @gordon thank you for that tool! I will definitely bookmark it for future use. 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. Jan 16, 2022 at 17:23

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.