Markdown Header Conversion Script

tl;dr

Bulk convert Markdown headers with double underlines and underlines to hash/pound/number sign style.

Markdown Header Styles

The original Markdown spec has two different styles of headers. One style using leading # characters and the other using - or = characters underneath the headers. For almost all of my documents I used the later style.

Converting Styles

As part of an update to how I use Markdown, I wanted to switch to the # style of headers. I had a couple hundred files, so I was hoping to bulk update all of the existing documents. After some false starts, the following are a series of commands that work, using find and sed.

Commands

The following were run on MacOS 10.14 (Mojave) but should work on any modern Unix command line.

The find command recursively searches for Markdown files (*.md) and calls sed to do a search and replace on each.

The sed code is a little weird, but it is based off the multi-line ‘\n’ expression here and prepending a new character(s) to a line when a match is found.

The first command removes all the trailing empty lines to clean up the files and avoid any sed errors.


find . -type f -name "*.md" -exec sed -i '' -e :a -e '/^\n*$/{$d;N;};/\n$/ba' {} \;

The second command matches with any row that has a new line followed by 3 or more = characters and replaces them with === on the end of the ‘parent’ line (removing the new line).


find . -type f -name "*.md" -exec sed -i '' -e :a -e '$!N;s/\n===.*/===/;ta' -e 'P;D' {} \;

The third command matches with any row that ends in ===, removes the characters and pre-pends the line with #.


find . -type f -name "*.md" -exec sed -i '' -E 's/(.+)(\=\=\=)/#\ \1/g' {} \;

The fourth and fifth commands repeat the above, but for - characters, replacing them with a pre-pended##.


find . -type f -name "*.md" -exec sed -i '' -e :a -e '$!N;s/\n---.*/---/;ta' -e 'P;D' {} \;

find . -type f -name "*.md" -exec sed -i '' -E 's/(.+)(\-\-\-)/##\ \1/g' {} \;

Final Script

From the command line, edit script:


vi ./markdown-updater.sh

And paste the following:


#!/bin/bash

find . -type f -name "*.md" -exec sed -i '' -e :a -e '/^\n*$/{$d;N;};/\n$/ba' {} \;

find . -type f -name "*.md" -exec sed -i '' -e :a -e '$!N;s/\n===.*/===/;ta' -e 'P;D' {} \;

find . -type f -name "*.md" -exec sed -i '' -E 's/(.+)(\=\=\=)/#\ \1/g' {} \;

find . -type f -name "*.md" -exec sed -i '' -e :a -e '$!N;s/\n---.*/---/;ta' -e 'P;D' {} \;

find . -type f -name "*.md" -exec sed -i '' -E 's/(.+)(\-\-\-)/##\ \1/g' {} \;

Finally, make executable:


sudo chmod u+x ./markdown-updater.sh

The script should be copied to the root of the directory containing Markdown files and run.

Comments are closed.