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
p
- option at the end of our's/search 1/replace 1/gp'
ensures we're printing.-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
-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
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
-i.bak
- Create a.bak
of the same file to use as our "changed" file