2026年9月17日
2026年9月17日
WP-CLIのsearch-replaceでURLや文字列を安全に一括置換する方法
ドメイン変更やHTTPS化でデータベース内のURLを書き換えるなら、WP-CLI の wp search-replace を使うのが安全です。シリアライズされたデータ(ウィジェットやテーマ設定など)の文字数情報も合わせて直してくれるため、SQL の REPLACE で起きがちな設定の破損を避けられます。この記事では、バックアップと --dry-run による事前確認から、本番の置換、対象テーブルの範囲、マルチサイトでの使い方、置換後の確認までを順に説明します。
作業前の準備:バックアップと環境の確認
wp search-replace はデータベースを直接書き換えるコマンドで、取り消し機能はありません。実行前にデータベースを書き出しておき、問題があれば戻せる状態にしておきます。
# WordPress のディレクトリで実行
wp db export ~/backup/before-replace-$(date +%Y%m%d-%H%M).sql
# 書き出したファイルのサイズを確認(0バイトなら失敗している)
ls -lh ~/backup/
ここで紹介するオプションは WP-CLI 2系を前提にしています(2026年10月現在)。オプションの細部はバージョンで変わることがあるため、wp cli version で手元のバージョンを確かめ、迷ったときは wp help search-replace を確認してください。本番サイトで初めて実行する場合は、同じデータを入れたステージング環境で一度通しておくと、想定外の置換に気づきやすくなります。
基本の書き方と --dry-run での事前確認
構文は wp search-replace '置換前' '置換後' です。最初はすぐ本番に流さず、--dry-run を付けて「どのテーブルのどの列で何件置換されるか」だけを確認します。
wp search-replace 'https://old.example.com' 'https://new.example.com' --dry-run
実行すると、テーブル名・列名・置換件数の表が表示され、データベースは変更されません。ここで見ておきたいのは次の3点です。
- 想定していないテーブルや列で大量に置換されていないか
- 件数が0の場合、表記ゆれ(
httpとhttps、wwwの有無、末尾スラッシュ)で一致していないだけではないか wp_usersのuser_emailなど、変えたくない列が含まれていないか
件数だけを見たいときは --format=count が便利です。変更のあった行だけを表示したいときは --report-changed-only を付けると、表が短くなり確認しやすくなります。
本番の置換を実行する
dry-run の結果に問題がなければ、--dry-run を外して実行します。ドメイン変更では guid 列を除外するのが一般的です。guid は投稿を一意に識別するための値で、URLの形をしていても変更しないことが推奨されています。
wp search-replace 'https://old.example.com' 'https://new.example.com' \
--skip-columns=guid --report-changed-only
置換後は、オブジェクトキャッシュやパーマリンクの設定を更新しておきます。
wp cache flush
wp rewrite flush
# サイトURLが変わったか確認
wp option get home
wp option get siteurl
キャッシュ系プラグインやCDNを使っている場合は、それぞれのキャッシュも削除してください。データベースを直しても、古いURLを含むページがキャッシュから配信され続けることがあります。
置換前の文字列はできるだけ長く指定する
old.example.com のように短い文字列で置換すると、メールアドレス(info@old.example.com)や、本文中でドメイン名に触れている文章まで書き換わります。基本は https://old.example.com のようにスキームから含めて指定し、HTTPで保存された古いリンクが残っている場合は、http://old.example.com について別途 dry-run と置換を行うと、意図しない箇所を巻き込みにくくなります。
対象テーブルの範囲を理解する
ここが最もつまずきやすい点です。wp search-replace は、何も指定しないと WordPress の $wpdb に登録されたテーブル(wp_posts、wp_postmeta、wp_options などのコアテーブル)だけを対象にします。プラグインが独自に作ったテーブルは、同じ接頭辞(wp_ など)が付いていても対象外になることがあります。
# 接頭辞が付いた全テーブルを対象にする
wp search-replace 'https://old.example.com' 'https://new.example.com' \
--all-tables-with-prefix --skip-columns=guid --dry-run
# 特定のテーブルだけを対象にする
wp search-replace 'https://old.example.com' 'https://new.example.com' wp_postmeta --dry-run
# 除外したいテーブルがある場合
wp search-replace 'https://old.example.com' 'https://new.example.com' \
--all-tables-with-prefix --skip-tables=wp_actionscheduler_logs --dry-run
SEOプラグインやフォームプラグインのテーブルにURLが保存されていると、コアテーブルだけを置換したあとも古いURLが残ります。まず --all-tables-with-prefix --dry-run で件数を確認し、どのテーブルに旧URLがあるかを把握してから範囲を決めると安全です。接頭辞の付かないテーブルまで含める --all-tables もありますが、同じデータベースに別システムのテーブルが同居している環境では、影響範囲が広がるため慎重に扱ってください。
マルチサイトでの使い方
マルチサイトでは、既定で --url= に指定したサイト(指定がなければメインサイト)のテーブルだけが対象になります。ネットワーク全体を置換する場合は --network を付けます。
# 特定の子サイトだけ
wp search-replace 'https://old.example.com/shop' 'https://new.example.com/shop' \
--url=https://old.example.com/shop/ --skip-columns=guid --dry-run
# ネットワーク全体
wp search-replace 'old.example.com' 'new.example.com' --network --skip-columns=guid --dry-run
マルチサイトのドメイン変更では、wp_blogs や wp_site のドメイン列、wp-config.php の DOMAIN_CURRENT_SITE も関係します。データベースの置換だけで終わらせず、wp-config.php の定数も合わせて見直してください。
移行先に流し込むSQLを作る:--export
サーバー移転では、現在のデータベースを変更せず、置換済みのSQLファイルだけを作りたい場面があります。--export を使うと、置換結果をファイルに書き出し、元のデータベースはそのまま残せます。
# 元のDBは変更せず、置換済みのSQLを書き出す
wp search-replace 'https://old.example.com' 'https://new.example.com' \
--skip-columns=guid --export=migrated.sql
# 移行先のサーバーで取り込む
wp db import migrated.sql
移行元のサイトを動かしたまま新環境を準備できるため、切り替え直前まで旧サイトを止めずに済みます。
置換がうまくいかないときの確認ポイント
件数が0、または一部だけ残る
まず表記ゆれを疑います。wp db search 'old.example.com' でデータベース全体を検索すると、旧ドメインがどのテーブル・列に、どんな形で残っているかを確認できます。
wp db search 'old.example.com' --all-tables
ページビルダーなどが JSON 形式でデータを保存している場合、URLのスラッシュが https:\/\/old.example.com のようにエスケープされていることがあります。この形は通常の指定では一致しないため、検索結果を見て保存形式を確認したうえで対処します。ビルダー側に専用のURL置換機能が用意されていることもあるので、利用中のビルダーのドキュメントも確認してください。
Base64 などで符号化されたデータ
一部のプラグインは設定値を Base64 などで符号化して保存します。この場合は文字列として一致しないため置換されません。対象プラグインの設定画面から保存し直すか、プラグインが用意している移行機能を使います。
正規表現を使いたい場合
--regex を付けると正規表現で置換できますが、処理はPHP側で行われるため大きなデータベースでは時間がかかります。パターンの誤りは影響が大きいので、dry-run で件数を確かめてから実行してください。
wp search-replace 'https?://old\.example\.com' 'https://new.example.com' \
--regex --skip-columns=guid --dry-run
SQL で直接 REPLACE してしまった
phpMyAdmin などで UPDATE ... REPLACE() を実行すると、シリアライズされた値の文字数が合わなくなり、ウィジェットやテーマ設定が読み込めなくなることがあります。この状態になったら、作業前のバックアップに戻してから wp search-replace でやり直すのが確実性の高い対処です。
まとめ
- 実行前に
wp db exportでバックアップを取り、まず--dry-runで置換件数を確認する - ドメイン変更では
--skip-columns=guidを付け、置換前の文字列はスキームから長めに指定する - 既定ではコアテーブルだけが対象。プラグインのテーブルも直すなら
--all-tables-with-prefixを検討する - マルチサイトは既定で1サイト分。全体を置換するなら
--network、wp-config.php の定数も見直す - 移行時は
--exportで置換済みSQLを作れる。残ったURLはwp db searchで探す