LAST_MODIFIED, SSIs, and sed

I use Apache's SSI (Server Side Includes) heavily on my website. A feature I use frequently is to create and show variables: the one I use most is "LAST_MODIFIED", which is the date the current page was last modified - the value is autogenerated by Apache. I'm moving my site to Nginx (I've become more familiar with it and it's lighter weight), but Nginx's SSI support doesn't include LAST_MODIFIED. So I'm looking for work-arounds. My new best friend is sed, an ugly and under-appreciated Unix utility for editing multiple files in a single pass. Like so many things Unix, it's actually surprisingly easy to use once you know how to use it. But until you know how to use it, getting started is the proverbial needle in a haystack. Unfortunately, the fix has been to hard-code the variable into the file. This works for me (but may not work for you) because I use Vim to edit files, and I've coded it to automatically update these values for me (that's how to use Vim to update RST files, it needs modification for HTML files).

I have a bunch of included ".pre" files (they're essentially HTML), and with the loss of LAST_MODIFIED, I've decided to create a new variable (GO_LAST_MODIFIED to not conflict with the original) to replace it. In this case I'm not checking that it hasn't already been added, because I know it hasn't. We'll get to that:

#!/bin/bash
for file in *.pre
do
    # use "date" to get a "reference" ("-r") date from the file, and
    # create it in our preferred format:
    lastmoddate="$(date -r "${file}" '+%Y-%m-%d %H:%M')"
    # use sed to edit "${file}", inserting a line at the beginning
    # that creates a new GO_LAST_MODIFIED variable to hold the date:
    sed -i.bak "1 i<!--#set var=\"GO_LAST_MODIFIED\" value=\"${lastmoddate}\" -->" "${file}"
done

A similar exercise, but on ".rst" files for this Pelican-based blog:

#!/bin/bash
for file in $(grep -L ":modified:" *.rst)
do
    lastmoddate="$(date -r "${file}" '+%Y-%m-%d %H:%M')"
    sed -i.bak "/:date:/a:modified: ${lastmoddate}" "${file}"
done

I'm checking first to see if the file already includes a ":modified:" tag. grep -L ... checks for the specified tag, then shows us a listing only of files that don't match (and it doesn't show you the text that it matched). With that file list, we do much the same thing: grab the last modified date from the file with date -r ... in my preferred date format, then search for the ":date:" tag and append the new line with a ":modified:" tag and our retrieved date right after it. This script could be improved by only searching the top ten lines (where the RST header lines are stored), and only matching if ":date:" is found at the beginning of the line ("^"), so:

$ sed -i.bak '1,10 {
/^:date:/a:modified: 2019-01-01 11:11
}' test.rst

This proved impossible (for me, anyway) to compress into a one-liner, as escaping the closing brace ("}") so that sed recognizes it as the end of the statement rather than a continuation of the "a" command is ... difficult.

Notice that I'm using sed's -i option throughout to store the original file as a ".bak" file in case I messed up: blind bulk editing is a dangerous practice, so significant checking is called for.