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 (|
).