Adding an ID property to Org-mode files in directory
This is a bit esoteric, but I’m writing it down here anyway.
I have switched between using Denote and Org-roam for my Org-mode notes several times. They are mostly compatible, so this hasn’t been too troublesome.
One thing I needed to do was make sure that all the .org files included an :ID: property at the top so that Org-roam includes them in its database. The ID property looks like this:
:PROPERTIES:
:ID: 4def7046-3ef8-4436-a079-09362bf66aff
:END:
Many of my Denote files already include this because I like to drag and drop files and images into the notes, and the ID property makes this work correctly. But there were maybe 300 files without an ID, and I had no desire to add the property manually to every one of them.
I started to write a shell script to do this, but got hung up on some bit of syntax, so I searched for the error and found the fix. Then I had trouble with the sed command, etc.
Sometimes I forget that ChatGPT exists. Sometimes I ignore it because I want to learn stuff on my own. But sometimes I just want the answer, and, problematic as LLMs can be, there’s no denying their usefulness.
A couple of prompts, a few iterations, and I had what I needed in about 10 minutes.
#!/bin/bash
# Directory containing the Org-mode files
ORG_DIR="" # Defaults to current directory if not provided
# Loop through all .org files in the specified directory
for; do
# Skip if no Org-mode files are found
[ || continue
# Check if the :ID: property exists in the first 5 lines
if ! | ; then
# Generate a unique ID (UUID)
id=
# Create the :PROPERTIES: block with the :ID:
properties_block=":PROPERTIES:\n:ID: \n:END:"
# Insert the :PROPERTIES: block at the very top of the file
else
fi
done
The only change I needed to make was to substitute gsed for sedbecause the macOS version of sed was missing a switch and throwing an error.
While I was in there, I asked ChatGPT for a version of the script in Emacs lisp, just in case. I had it write the function for use in a Dired buffer, since that’s where I’m most likely to want it. Here’s the function…
Done and done. There may be better, cleaner ways to do this, but my problem is solved, which is all I wanted.