02/01/2023 11:47 | Category: bash

Tags: linuxbashsedtip

complex sed replace with dry run testing to make sweeping repository changes

Recently I came across a need to make sweeping repository changes across many repos and thought that sed would be the best way to accomplish this.

I used a few references for learning how to do a dry run (print the change but don't execute it) as well as doing a recursive call with the sed replacement on specific file types.

References

Bonus

If you want multiple file types/names to be included:

find . -type f \( -name 'something' -o -name 'else.txt' -o -name '*.go' \)

Note: I've written another note for this as well!

Breaking down the sed call

There are a few components to the sed call that I settled on, with 2 separate commands that do different things.

Dry runs with find

In this command we utilize a few separate options to accomplish our goal.

find . -type f -name '*.<my file extension>' -readable -writable -exec sed -n 's/<search string>/<replace string>/gp' {} \;

The output of this will illustrate the exact changes that would take place.

Options

  1. p - option at the end of our 's/search 1/replace 1/gp' ensures we're printing.
  2. -n - a "--quiet" execution

Running the actual sed

To remove the dry run portion of the above we take out p and change -n to -i.

find . -type f -name '*.<my file extension>' -readable -writable -exec sed -i 's/<search string>/<replace string>/g' {} \;

Options

  1. -i - Change "in place"

Dry runs with grep interactivity

Below we use grep to find (interactively) our changes. This is doing effectively the same thing as what we did above, just using grep to find the lines themselves and piping the lines returned to our sed.

grep -rl --null "<search term>" | xargs -0 sed -e 's/<search term>/<replace term>/gp' | less

Options

  1. grep --null | xargs-0 - Terminates filenames by null-byte making it safe for

filenames with unutual characters

Using sed with a backup file

In the following command we use a .bak extension to append to our files, this allows us to verify our changes using the diff command.

grep -rl --null "<search term>" | xargs -0 sed -i.bak -e 's/<search term>/<replace term>/'
diff my-file.bak my-file

Options

  1. -i.bak - Create a .bak of the same file to use as our "changed" file