Extracting ID3 tags from the command line - two methods

As part of a Hazel rule to process downloaded mp3 files, I worked out a couple different methods for extracting the ID3 title tag. Not rocket science, but it took a little time to sort out. Both rely on non-standard third-party tools, both for parsing the text and for extracting the ID3 tags.

Extracting ID3 title with ffprobe

ffprobe is part of the ffmpeg suite of tools which on macOS can be installed with Homebrew. If you don’t have the latter, go install it now; because it opens up so many tools for your use. In this case, it makes ffmpeg available via brew install ffmpeg.

With that in place, extracting the title is just:

title=$(ffprobe -loglevel error -show_entries format_tags=title -of 
   default=noprint_wrappers=1:nokey=1 $file)

Extracting ID3 title with id3info

id3info is part of the id3tool suite of tools installed using - you guessed it - Homebrew. This solution also uses sd (brew install sd.) The latter is a more intuitive search and displace tool than the old stand-by sed.

for ln in $( id3info $file ); do
    if echo $ln | grep -q "TIT2"
        tit2=$( echo $ln | sd '.*TIT2.*: (.*).*' '$1' );

Or a one-liner using perl:

echo $( id3info $file ) | perl -ne 'print $1 if /TIT2.*?\:\s+(.*?)\s===/;'


  • sd - intuitive search and displace - a sed replacement
  • ffmpeg - play, record, convert, and stream audio and video
  • id3tool - ID3 editing tool
  • Bash for loop - a short tutorial on the Bash for loop - something that I wasn’t really proficient at. Always good to revist.

Using variables in Keyboard Maestro scripts

Having fallen in love with Keyboard Maestro for its flexibility in macOS automation, I began experimenting with scripting in various languages, like my old favourite Perl. That’s when the fun began. How do we access KM variables inside a Perl script.

Let’s see what the documentation says:

So the documentation clearly states that this script


print scalar reverse $KMVAR_MyVar;

should work if I have a KM variable named MyVar. But, you guessed it - it does not.

After digging around in the Keyboard Masestro forums, I found an obscure post that pointed the way. It turns out that the Perl access to KM variables is completely different from what the documentation claims, the format is not $KMVAR_MyVar, it is actually:


so the above script works if the variable is accessed from Perl that way:


print scalar reverse $ENV{KMVAR_MyVar};

Hugo cache busting

Justification Although caching can make page loads notably faster, it comes with a cost. Browsers aren’t always capable of taking note when a cached resource has changed. I’ve noticed recently that Safari utterly refuses to reload .css files even after emptying the browser cache and clearing the web history. Background With a lot of help from the a pair of articles written by Ukiah Smith, I’ve developed a workflow for dealing with this problem during the deployment process.

iOS shortcut to clear Safari

(N.B. The next installment in my obsessional interest in thwarting surveillance capitalism. Read Shoshana Zuboff’s seminal work on the subject and you’ll see.) Justification Last week I outlined my evolving comprehensive approach to thwarting surveillance capitalism - that is the extraction, repurposing and selling of online behavioural surplus for the purposes of altering future behaviour. This is a simple iOS shortcut to the embedded Safari setting for clearing Safari history and website data.

My macOS and iOS security setup - Update 2020

(N.B. I am not a security expert. I’ve implemented a handful of reasonable measures to prevent cross-site tracking and limit data collection about my preferences and actions online.) Surveillance capitalism is a real and destructive force in contemporary economics, politics and culture. Whatever utopian visions that Silicon Valley may have had about the transformative power of ubiquitous network technologies have been overwhelmed by the pernicious and opaque forces that profit from amplifying divisions between people.

A macOS text service for morphological analysis and in situ marking of Russian syllabic stress

Building on my earlier explorations of the UDAR project, I’ve created a macOS Service-like method for in-situ marking of syllabic stress in arbitrary Russian text. The following video shows it in action: The Keyboard Maestro is simple; we execute the following script, bracketed by Copy and Paste: #!/Users/alan/.pyenv/shims/python3 import xerox import udar import re rawText = xerox.paste() doc1 = udar.Document(rawText, disambiguate=True) searchText = doc1.stressed() result = re.sub(r'( ,)', ",", searchText) xerox.

Solzhenitsyn on the folly of looking for good/evil dichotomies

Постепенно открылось мне, что линия, разделяющая добро и зло, проходит не между государствами, не между классами, не между партиями, — она проходит через каждое человеческое сердце — и черезо все человеческие сердца. Линия эта подвижна, она колеблется в нас с годами. Даже в сердце, объятом злом, она удерживает маленький плацдарм добра. Даже в наидобрейшем сердце — неискоренённый уголок зла. Alexander Solzhenitsyn Gulag Archipelago My rough translation to English:

On not minding what happens

Over-involvement in the future must be our most maladaptive trait. Back in the 1970’s in Ojai, when Jiddu Krishnamurti drew enormous crowds to his extemporaneous talks, he touched on the liberation that comes from releasing the pointless hold on the future.1 Do you want to know what my secret is? You see, I don’t mind what happens. Jiddu Krishnamurti Lecture, Ojai,California, USA; late 1970's That’s it. Of all the teachings from the broad wisdom traditions, his one secret was not minding what happens.

We're all imposters

Reading Oliver Burkeman’s last advice column in decade-long series in The Guardian, I was struck by his advice on the imposter syndrome: The solution to imposter syndrome is to see that you are one…Humanity is divided into two: on the one hand, those who are improvising their way through life, patching solutions together and putting out fires as they go, but deluding themselves otherwise; and on the other, those doing exactly the same, except that they know it.

The Buddha was a list-maker

Beginning with “The Four Noble Truths”1, “The Noble Eightfold Path”2, and so on, the Buddha was a list-maker. I recently found a wonderful book, now out of print but freely available as a pdf. By David Snyder, Ph.D., it is called “The Complete Book of Buddha’s Lists - Explained” Snyder does a brilliant job of reinterpreting these lists and framing them in the context of what the social sciences say about how we function individually and in groups.