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 で探す

お気軽にご相談ください

お見積りへ お問い合わせへ
▲