A deliberately inefficient automation

I automate computer tasks for one of four reasons:

  1. Speed. This is the obvious one, the reason everybody thinks of as the main reason for automation.
  2. Accuracy. When I have to do a series of steps over and over again, my mind tends to wander, and I make mistakes. A well-written script or macro prevents those kinds of errors.
  3. Focus. When I’m writing, I like to keep my mind on what I’m trying to say, not on formatting or other side issues. Using Markdown helps for this, but so does using scripts and Typinator (or TextExpander) snippets for certain boilerplate text.
  4. Learning. Sometimes I take far more time to create an automation than I will ever get back. I do it anyway because I want to learn an automation technique that might come in handy later. Or I just want to learn it because learning is fun.

I recently had a close encounter with an automation of the fourth kind.

In the latest episode of the Sophomore Lit podcast, John McCoy and Jelani Sims covered A Canticle for Leibowitz, the post-apocalyptic science fiction novel by Walter M. Miller, Jr. During the episode, they mentioned a National Public Radio dramatization of the book, and I told myself I should go find that and listen to it. Of course, I immediately forgot, but luckily Kieran Healy had me covered. He posted a link to the dramatization on Mastodon, and this time I didn’t forget to download the files.

The dramatization was presented over 15 episodes, each about half an hour long. When I downloaded the MP3s, they had the unhelpful file names 01.mp3, 02.mp3, and so on up through 15.mp3. I used the Finder’s Rename… command to change their names to the more useful Canticle-01.mp3 through Canticle-15.mp3. Then I sideloaded them into Castro and listened to them as a podcast.

A Canticle for Leibowitz MP3 artwork

But I found a problem. A Canticle for Leibowitz is organized into three sections that are separated by several centuries. The ID3 tags of the MP3 files use these sections in the track titles, and Castro uses the track titles as the names of sideloaded episodes. Here’s the organization:

File name Track title
Canticle-01.mp3 500 Years After, part 1
Canticle-02.mp3 500 Years After, part 2
Canticle-03.mp3 500 Years After, part 3
Canticle-04.mp3 500 Years After, part 4
Canticle-05.mp3 1100 Years After, part 1
Canticle-06.mp3 1100 Years After, part 2
Canticle-07.mp3 1100 Years After, part 3
Canticle-08.mp3 1100 Years After, part 4
Canticle-09.mp3 1100 Years After, part 5
Canticle-10.mp3 1100 Years After, part 6
Canticle-11.mp3 1100 Years After, part 7
Canticle-12.mp3 1800 Years After, part 1
Canticle-13.mp3 1800 Years After, part 2
Canticle-14.mp3 1800 Years After, part 3
Canticle-15.mp3 1800 Years After, part 4

Unfortunately, the track titles of seven of these files are incorrect. Canticle-05.mp3 is Part 5 of the “500 Years After” section, not Part 1 of the “1100 Years After” section. And the following six files are off by one in their part numbers.

So I wanted to fix the names.1 I have the Python Mutagen module installed on my Mac, and it comes with a command-line tool, mid3v2, that lets you view, set, and delete ID3 tags. Fixing Canticle-05.mp3 was easy

mid3v2 -t "500 Years After, part 5" Canticle-05.mp3

I could, of course, repeat this command with minor edits to change the track titles of Canticle-06.mp3 through Canticle-11.mp3, but where’s the fun in that? No, I wanted to do it all at once with a single shell command.

After quite a while, I came up with a solution that used looping, brace expansion, and arithmetic expansion. Here it is, spread out over three lines:

for n in {1..6}; do
printf "mid3v2 -t \"1100 Years After, part %d\" Canticle-%02d.mp3\n" $n $((n+5))
done

The key is the placeholders %d and %02d in the second line. The printf command replaces them with $n and $((n+5)) each time through the loop, so the result is

mid3v2 -t "1100 Years After, part 1" Canticle-06.mp3
mid3v2 -t "1100 Years After, part 2" Canticle-07.mp3
mid3v2 -t "1100 Years After, part 3" Canticle-08.mp3
mid3v2 -t "1100 Years After, part 4" Canticle-09.mp3
mid3v2 -t "1100 Years After, part 5" Canticle-10.mp3
mid3v2 -t "1100 Years After, part 6" Canticle-11.mp3

which are the six commands needed to change the track titles of those files. Once I saw that these were correct, I could run them all by piping this output to bash:2

for n in {1..6}; do
printf "mid3v2 -t \"1100 Years After, part %d\" Canticle-%02d.mp3\n" $n $((n+5))
done | bash

Thus concludes the retitling.

Given that’s it’s unlikely that I’ll listen to A Canticle for Leibowitz again, you might consider this even more a waste of time than I originally suggested. Not only did I spend more time figuring out how to change the ID3 tags in a single command than I would have just writing out six commands, I made the changes on files that I’ll never use again.

But I did learn some shell scripting techniques, and I got the satisfaction of solving a problem in a language I’ve never been comfortable with.


  1. We won’t get into another problem I have with the names, which is that I think the time peroids should be 600, 1200, and 1800 years after the Flame Deluge. Or that the parts should have the names “Fiat Homo,” “Fiat Lux,” and “Fiat Voluntas Tua,” as they do in the book. 

  2. I should mention here that I’m using version 5.2.26 of bash, installed via Homebrew, not the old version that comes with macOS. Some of the features used in this command may not work with old bash. I could have piped the output to zsh and it would have worked (I just checked), but I’m just not in the habit of using zsh