If you’ve ever tried to use dengste/org-caldav: Caldav sync for Emacs orgmode to synchronize your org calendar, you may have noticed that it adds an ID to all headings by design. For some, these extra PROPERTIES blocks can be quite distracting. To address this, I proposed a patch to create IDs for only relevant headings here: https://github.com/dengste/org-caldav/issues/227.

However, if it’s already too late, here is a script to clean things up. You can evaluate it to remove all IDs that are neither a target, have attachment(s), nor a timestamp (synced with CalDAV). It assumes everything is in the ~/org directory, including archived files, and requires the use of rg, jq, and awk. Please back up your org files before running it (presumably via git) and run org-lint to verify that nothing is broken.

(let* ((default-directory (expand-file-name "~/org"))
       (ids (-> (shell-command-to-string
                 "rg -a -g '*.org*' --json '^:ID:\s*([A-Za-z00-9\-])+\s*$'  | jq -r '.data.submatches | select(.) | .[].match.text' | awk '{ print $2 }' | sort")
                (split-string "\n")))
       (targets (-> (shell-command-to-string
                     (format "rg -a -g '*.org*' --json '\\[id:(%s)]' | jq -r '.data.submatches | select(.) | .[].match.text[4:-1]' | sort" (string-join ids "|")))
                    (split-string "\n")))
       (not-targets (seq-difference ids targets)))
    (seq-each #'(lambda (id)
                  (condition-case nil
                        (org-id-goto id)
                        (unless (or (org-entry-get nil "SCHEDULED")
                                    (org-entry-get nil "DEADLINE")
                                    (org-entry-get nil "TIMESTAMP")
                                    (member "ATTACH" (org-get-tags nil t)))
                          ;; (message "DELETE %s" id)
                          (org-delete-property "ID")))
                    (error (message "FALSE POSITIVE %s" id))))