Creating a post template with bash & sed

Quarto
bash
sed
Published

2023-12-31


There’s some boilerplate that I include in all my posts and I wanted to streamline the process of generating a new post, so I created a Quarto file to use as a template:

---
title: "dummy-title"
categories: []
date: "dummy-date"
draft: true
---

<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css" integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
</head>

<hr>

<center><i class="fa fa-terminal" aria-hidden="true"></i></center>

For convenience, I wrote a simple command line tool that uses this template to setup a new post using. There are a few things that this tool needed do:

These three tasks are performed in the following bash script:

#!/usr/bin/env bash

unset -v filename
unset -v title

while getopts f:t: opt; do
  case $opt in
    f) filename="$OPTARG";;
    t) title="$OPTARG";;
    \?) echo "Invalid option -$OPTARG" >&2
        exit 1
  esac
done

if [ -z "$filename" ] || [ -z "$title" ]; then
  echo 'filename (-f) & title (-t) are mandatory arguments' >&2
  exit 1
fi

if test -f "posts/$filename.qmd"; then
    echo "File already exists"
    exit 1
fi

sed "s/dummy-title/$title/; s/dummy-date/$(date --iso-8601)/" \
    template.qmd \
    > posts/$filename.qmd

echo "$filename.qmd file created in posts/"

First, you’ll notice the shebang at the top to run the script with bash. Next, I unset the variables that I’m going to define later in the script by parsing the command line arguments. This is to ensure that they are not set in this environment so that I can check that they have indeed been set by the user. That’s done the if block, which follows. The second if block checks that I’m not trying to overwrite an existing file.

Finally, the fun part: sed! In the sed expression, s indicates that I want to substitute the string that follows (dummy-title) with another string (i.e., whatever value is held by the title variable). sed does something similar with the date, replacing dummy-date with the current date in ISO8601 format. The final argument passed to sed is the name of the template (imaginatively called template.qmd). The output from this is then directed into a file with the specified name in the post directory.

sed is a UNIX utility that has been around since Version 7 UNIX and has remained unchanged ever since. Later, the Free Software Foundation GNU project made a freely available version. sed is called a stream editor as input text flows through it, is modified in accordance with the given commands, and is then written to standard output. You’ll notice that in my script, I direct this standard output into a file.

To run this script (after chmod +x new-post to make the script executable), I use the following command:

$ ./new-post -t 'Creating a post template with bash \& sed' -f 'templating'
templating.qmd file created in posts/

Notice that I specify the file name after the -f flag and the post title after the -t flag.

Note that when I invoked this command I had to escape the ampersand with a backslash.

And that’s how the skeleton of this post was created!

Back to top