-
Correcting Date Tags using sed in an Entire Obsidian Vault
I’ve been using Obsidian for about 8 months. It wasn’t until today that I realized I’ve been using hierarchical tags incorrectly since day one!
The Problem
In my templater templates I was using the following:
1#<% tp.date.now("YYYY-MM-DD") %>/<% tp.date.now("YYYY-MM") %>/<% tp.date.now("YYYY") %> #<% tp.date.now("YYYY-MM-DD") %>The result of this is:
1#2022-03-17/2022-03/2022 #2022-03-17Unfortunately there are two problems with this. First, there is no need for that extra tag at the end; it’s already covered by the first combo tag.
Second, the hierarchy is backwards! This leads to:
123456├── 2022-03-16│ └── 2022-03│ └── 2022└── 2022-03-17└── 2022-03└── 2022Houston, we have a problem! What I really was after was a tag structure like this:
1234└── 2022└── 2022-03├── 2022-03-16└── 2022-03-17The Fix
Thankfully, Obsidian stores all of the files on the filesystem natively, which means you can manipulate them using whatever tools you’d like.
Enter sed, a stream editor. Using sed and find, I was able to quickly resolve both of the issues above.
If I’d taken a little more time I would have handled both problems in one shot, but I did not. I fixed problem 2, then problem 1.
First, I cd’d into the root directory of my vault. Then…
1234567891011# Find markdown files, feed them to sed,# edit the file "in place" (modify them directly)# We use capture groups (the parentheses) to# essentially reverse the order of the tagsfind . -type f -name '*.md' -print0 | xargs -0 sed -E -i "" "s/#([0-9]{4}-[0-9]{2}-[0-9]{2})\/([0-9]{4}-[0-9]{2})\/([0-9]{4})/#\3\/\2\/\1/g"# Find #YYYY/YYYY-MM/YYYY-MM-DD #YYYY-MM-DD,# capturing the first tag to "\1"# Replace with the capture group (thereby dropping the second tag)find . -type f -name '*.md' -print0 | xargs -0 sed -E -i "" "s/(#[0-9]{4}\/[0-9]{4}-[0-9]{2}\/[0-9]{4}-[0-9]{2}-[0-9]{2}) #[0-9]{4}-[0-9]{2}-[0-9]{2}/\1/g"Finally, I updated all of my templater templates to drop the second tag and fix the first to be in the right order.
Obsidian picked up all of the changes immediately, which were reflected in the tag pane. Much cleaner!
-
Automatically Change Links from Absolute to Relative
In this example I’m showing one way to quickly convert all a href and img src paths from absolute to relative. It’s quite a time saver, but I suggest committing your latest changes before trying anything here! If you aren’t using a version control system, make a backup somewhere… please! Note: Both of these commands are one-liners.
1234567#BSD Version (Mac):find . -path './.git' -prune -o -type f -exec sed -i '' -E "s/(href|src) *= *([\"'])(https?:\/\/)?(www\.)?mysite\.(org|com)\//\1=\2\//g" {} \;#GNU Version:find . -path './.git' -prune -o -type f -exec sed -i -r "s/(href|src) *= *([\"'])(https?:\/\/)?(www\.)?mysite\.(org|com)\//\1=\2\//g" {} \;#You may consider using {} +; instead of {} \;In the examples/results below, I tried to target most situations. You should see subtle differences between each example.
1234567891011121314151617181920212223-<a href="https://www.mysite.org/basic_skills">This is another link</a>+<a href="/basic_skills">This is another link</a>-<a href="https://www.mysite.org/basic_skills">This is another link</a>+<a href="/basic_skills">This is another link</a>-<a href="http://www.mysite.org/basic_skills">This is another link</a>+<a href="/basic_skills">This is another link</a>-<a href="http://mysite.org/basic_skills">This is another link</a>+<a href="/basic_skills">This is another link</a>-<a href="www.mysite.org/basic_skills">This link points to http://www.mysite.org/basic_skills</a>+<a href="/basic_skills">This link points to http://www.mysite.org/basic_skills</a>-<a href="mysite.org/basic_skills">This is another link</a>+<a href="/basic_skills">This is another link</a>-<a href="http://www.mysite.com/basic_skills">This is the last link</a>+<a href="/basic_skills">This is the last link</a>-<img src="https://www.mysite.org/testing123.jpg">+<img src="/testing123.jpg">