When you migrate a WordPress site or WooCommerce store to a new domain you may find some URLs or paths were not updated. Similarly when switching from http to https you may get some mixed content errors, usually this can be fixed by updating the database. Traditionally there are some plugins and scripts that help you update the database to resolve these issues, if you still have problems this post should help you fix paths and URLs in your WordPress database.
I first encountered this issue when I discovered a plugin (looking at you Ultimate VC Add-ons) likes to encode the colon and slashes differently like this http%3A%2F%2F
I will assume you already have a WordPress database dump created with phpMyAdmin, Adminer (plugin), MySQL dump or WP-CLI.
Advanced WordPress Search Replace Database with Linux using sed
I am going to use the Linux tools grep
and sed
for maximum speed. If you do not have access to Linux then you can use the WordPress plugin Better Search and Replace.
Finding Occurences
We can simulate a dry run with grep, using the -c
flag it will count the amount of times it finds the domain.com string
grep -c 'wp-bullet.com' database.sql
You will get an integer as output, if you see 0
then there are no occurrences of domain.com in the database
4513
URL Encoded
Some plugins use URL encoding which uses this format for http and https migration %3A = :
and %2F = /
.
To verify whether you have any of these in your database use this command
grep -c 'http%3A%2F%2F' database.sql
Serialized Arrays – Escaped Slashes
Some plugins escape slashes with \/
and can easily be missed because of the serialized content in json format.
grep -c 'http:\/\/domain.com' database.sql
WordPress Path
Sometimes plugins store information about the storage path on your host, find out by using this command
grep -c '/public_html/domain.com' database.sql
Actual replacement
Many tutorials use
as the delimiter for /
sed
, I am using #
to make it easier to read. It also means you will not have to escape any slashes (\/
) in your sed command.
The g
signifies a global replacement and the >
redirects to a new file so you do not modify the original database dump.
This command replaces domain.com
with newdomain.com
in the dump.sql file
sed 's#domain.com#newdomain.com#g' dump.sql > staging-or-newdomain.sql
In this example, there is a subfolder for the WordPress installation, the #
helps maintan readability
sed 's#domain.com/oldfolder#newdomain.com/newfolder#g' dump.sql > staging-or-newdomain.sql
URL Encoded
Replacing URL encoded strings
sed 's#http%3A%2F%2Fdomain.com#http%3A%2F%2Fnewdomain.com#g' dump.sql > staging-or-newdomain.sql
This is how to replace domains with subfolders and URL encoded strings
sed 's#http%3A%2F%2Fdomain.com%2Fsubfolder#http%3A%2F%2Fnewdomain.com%2Fsubfolder#g' dump.sql > staging-or-newdomain.sql
Escaped Slashes – Serialized Data
If you have escaped slashes this command will do the trick
sed 's#http:\/\/domain.com#http:\/\/newdomain.com#g' dump.sql > staging-or-newdomain.sql
WordPress Path Search and Replace
Replacing a path
sed 's#/public_html/wp-bullet.com#/public_html/newfolder#g' dump.sql > staging-or-newdomain.sql
That should take care of most WordPress databases, let me know if you find any other unconventional patterns in the comments!
Using Gzip to Compress New Dump
We can compress the modified dump with gzip easily to shrink the .sql file significantly
cat dump.sql | gzip > dump.sql.gz
Now you can re-import the modified dump using WP-CLI, phpMyAdmin or Adminer.
Sources
Save sed Output to a File
Count the Number of Occurrences of a String
URL Encoding
URL Encoding Reference
This is like the holy grail for wordpress bash. Thanks a bunch!
That’s basically fine because WP ignores serialized content lengths but its surely not the holy grail for bash 😉 .
Its much better to setup wp-cli.org way to use it for WP as documented in https://developer.wordpress.org/cli/commands/search-replace/
Found this page because I was searching for a better common/non-WP solution like
https://interconnectit.com/products/search-and-replace-for-wordpress-databases/ => https://github.com/interconnectit/Search-Replace-DB
with easier setup like this GO based solution https://josh.blog/2019/03/search-replace-php-serialized-strings (best in different language or as Debian Package for easy setup on instances).
Thanks for your comment Reiner, we love WP-CLI here! But PHP is not exactly the fastest language (neither is Go 😉 but I would love to see benchmarks comparing sed to Josh’s Go-based solution) so this post was intended to show alternatives where speed is of the essence like on gigantic database dump files.
Ive found this pattern in some of my wordpress sql files.
http:\/\/old-domain.com\
When I try and use this sed statement it doesn’t seem to work. Any ideas?
sed 's#http:\/\/old-domain.com\#https:\/\/new-domain.com\#g' input.sql > output.sql
Here you go Craig, it has to do with escaping the special characters:
Reference https://unix.stackexchange.com/questions/379572/escaping-both-forward-slash-and-back-slash-with-sed