Quick Codemods with sed

Posted on in programming

I had a few different changes last week (in two different repos) that required one-line changes in lots of files.

Quick note here that I'm using GNU sed. If you're on a Mac, you can use GNU sed, too (via Homebrew, for example).

Example 1: Change Status

In this first example, I wanted to change the status of 120+ posts from "published" to "hidden". These files all contained "eol" in their names, so this one was a breeze.

for FILE in *eol*; do
    sed -i "s/: published/: hidden/" $FILE
done

The s command at the beginning of the script indicates we're going to match the regular expression on the left-hand side and replace it with the right-hand side.

Example 2: Change Some HTML

In this next example, I was changing some markdown. I get a list of files to act on by using grep to find files with the content and then using cut to separate the file names from the line containing the file. Finally, sed does the work (not much different than the previous example.)

for FILE in $(grep -r alignright content | cut -d: -f1); do
    sed -i 's/\.alignright/align="right"/g' $FILE;
done

The one difference here is that I've added the g flag to indicate this command should run multiple times throughout the file (not just on the first match).

Example 3: Bazel Package Change

Here I wanted to replace all instances of one Bazel package with another.

for FILE in $(find . -name BUILD); do 
    sed -i 's|@bazel_tools//tools/build_defs/pkg:pkg.bzl|//bazel/rules:pkg.bzl|' $FILE;
done

These are Bazel BUILD files, so I use find to find all the files named BUILD. In the s command, I don't want to have to add a leading backslash (\) to all the forward slashes (/), so I replace the delimiters with pipes (|).

sed

Slaptijack's Koding Kraken