Bulk conditional file name change

terminal

I've been doing a lot of organising of my files using terminal commands (mostly for further terminal education).
I've learned about bulk renaming in terminal, e.g. replacing all underscores with spaces, bulk case changes, etc.

What I'm trying to do now is insert a character, or set of characters, either in a specific place in the file name or conditionally.

Essentially I'm trying to add a hyphen "-" between the track number and title of a list of audio files.

So where I have:
"01 First Track.mp3"
"02 Second Song Title.mp3"
"03 Third.mp3"
"04 Fourth and Final One.mp3"

I'd like to replace the " " in the third position to be " – ", leaving:
"01 – First Track.mp3"
"02 – Second Song Title.mp3"
"03 – Third Thing.mp3"
"04 – Fourth and Final One.mp3"

Is there a way to append a character conditionally? Say, check for a number (anything between 0-9), and replace the character directly after with another character? Logically: for i in *; if $i === "0-9" and + === " " replace + with " – " …. something like that?

Alternatively, could I just point to the third position of the file name and insert "- "?

The problem with simply replacing ALL " " with " – " is that this would replace each space in the file name with a hyphen.

Perhaps there is a way to only consider the first instance of the " " in the file name and ignore later instances?

But I'd like to learn if there is a way to replace characters conditionally.
I've been googling with:
"terminal bulk replace character conditional"
"unix batch file name conditional"

and similar, but so far have only found character removal/replacement, or plain appending (i.e. replace all X with Y, or for each file, append a sequential number to the beginning).

Many thanks.

Best Answer

You probably want to use regex for this. Depending on the version of your question, it's pretty straightforward. There are a number of good sites to get started on the basics. In a sense, you already have seen a little taste of it: the "*" in "*.mp3" is a regex concept (meaning 'match any symbol 0 or more times'). Try something like (https://www.debuggex.com) or (http://www.regexr.com).

The simple version of your question is actually very simple indeed, so you might get away with just this approach:

echo '01 ab cd.mp3' | sed 's/ / - /'

This sed command is basically a regex-defined find and replace. It finds ' ' and replaces it with ' - ', the first time only. (Much more on sed here: https://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022-Command)

I would also be surprised if there weren't a number of scripts and things specifically for processing mp3 filenames that will already do this for you, but there's no reason you can't do it yourself in Terminal.