はなゐろぐ

主に技術関係の覚え書きです。

wp-cliでデータベース内を検索・置換する

2020年4月21日

カスタムフィールドを含めた記事内の全てのURLを絶対パスからルート相対パスに置換することがありまして。記事数が多かったので手動は避けたいと思い、Search Regexを試しました。しかし複雑なサブフィールドまでは検索できなかったのでさらに調べたところ、wp-cliで置換できるとのことで試してみました。

wp search-replace – WP-CLI Command | Developer.WordPress.org
Searches/replaces strings in the database.
wp search-replace – WP-CLI Command | Developer.WordPress.org favicon https://developer.wordpress.org/cli/commands/search-replace/
wp search-replace – WP-CLI Command | Developer.WordPress.org

wp search-replace <置換前> <置換後>でデータベース内のテキストを検索・置換できます。今回は使っていませんが、正規表現でも検索可能なようです。

※データベースを直接変更するので、必ず事前にバックアップを取っておきましょう。

作業の流れ

まずは—dry-runオプションをつけて、実際には置換せず検索だけかけます。

$ wp search-replace '{置換したいURL}' '/' --dry-run
+------------------+-----------------------+--------------+------+
| Table            | Column                | Replacements | Type |
+------------------+-----------------------+--------------+------+
| wp_commentmeta   | meta_key              | 0            | SQL  |
| wp_commentmeta   | meta_value            | 0            | SQL  |
| wp_comments      | comment_author        | 0            | SQL  |
| wp_comments      | comment_author_email  | 0            | SQL  |
| wp_comments      | comment_author_url    | 0            | SQL  |
| wp_comments      | comment_author_IP     | 0            | SQL  |
| wp_comments      | comment_content       | 0            | SQL  |
| wp_comments      | comment_approved      | 0            | SQL  |
| wp_comments      | comment_agent         | 0            | SQL  |
| wp_comments      | comment_type          | 0            | SQL  |
| wp_links         | link_url              | 0            | SQL  |
| wp_links         | link_name             | 0            | SQL  |
| wp_links         | link_image            | 0            | SQL  |
| wp_links         | link_target           | 0            | SQL  |
| wp_links         | link_description      | 0            | SQL  |
| wp_links         | link_visible          | 0            | SQL  |
| wp_links         | link_rel              | 0            | SQL  |
| wp_links         | link_notes            | 0            | SQL  |
| wp_links         | link_rss              | 0            | SQL  |
| wp_options       | option_name           | 0            | SQL  |
| wp_options       | option_value          | 1            | PHP  |
| wp_options       | autoload              | 0            | SQL  |
| wp_postmeta      | meta_key              | 0            | SQL  |
| wp_postmeta      | meta_value            | 956          | PHP  |
| wp_posts         | post_content          | 437          | SQL  |
| wp_posts         | post_title            | 0            | SQL  |
| wp_posts         | post_excerpt          | 0            | SQL  |
| wp_posts         | post_status           | 0            | SQL  |
| wp_posts         | comment_status        | 0            | SQL  |
| wp_posts         | ping_status           | 0            | SQL  |
| wp_posts         | post_password         | 0            | SQL  |
| wp_posts         | post_name             | 0            | SQL  |
| wp_posts         | to_ping               | 0            | SQL  |
| wp_posts         | pinged                | 0            | SQL  |
| wp_posts         | post_content_filtered | 0            | SQL  |
| wp_posts         | guid                  | 5361         | SQL  |
| wp_posts         | post_type             | 0            | SQL  |
| wp_posts         | post_mime_type        | 0            | SQL  |
| wp_term_taxonomy | taxonomy              | 0            | SQL  |
| wp_term_taxonomy | description           | 0            | SQL  |
| wp_termmeta      | meta_key              | 0            | SQL  |
| wp_termmeta      | meta_value            | 0            | SQL  |
| wp_terms         | name                  | 0            | SQL  |
| wp_terms         | slug                  | 0            | SQL  |
| wp_usermeta      | meta_key              | 0            | SQL  |
| wp_usermeta      | meta_value            | 0            | PHP  |
| wp_users         | user_login            | 0            | SQL  |
| wp_users         | user_nicename         | 0            | SQL  |
| wp_users         | user_email            | 0            | SQL  |
| wp_users         | user_url              | 0            | SQL  |
| wp_users         | user_activation_key   | 0            | SQL  |
| wp_users         | display_name          | 0            | SQL  |
+------------------+-----------------------+--------------+------+

wp_optionsの中にあるサイトURLなどの設定を含めないよう、今回はwp_posts(投稿)とwp_postmeta(カスタムフィールド)のテーブルに絞ります。

$ wp search-replace ‘{置換したいURL}’ '/' wp_posts wp_postmeta --dry-run
+-------------+-----------------------+--------------+------+
| Table       | Column                | Replacements | Type |
+-------------+-----------------------+--------------+------+
| wp_postmeta | meta_key              | 0            | SQL  |
| wp_postmeta | meta_value            | 956          | PHP  |
| wp_posts    | post_content          | 437          | SQL  |
| wp_posts    | post_title            | 0            | SQL  |
| wp_posts    | post_excerpt          | 0            | SQL  |
| wp_posts    | post_status           | 0            | SQL  |
| wp_posts    | comment_status        | 0            | SQL  |
| wp_posts    | ping_status           | 0            | SQL  |
| wp_posts    | post_password         | 0            | SQL  |
| wp_posts    | post_name             | 0            | SQL  |
| wp_posts    | to_ping               | 0            | SQL  |
| wp_posts    | pinged                | 0            | SQL  |
| wp_posts    | post_content_filtered | 0            | SQL  |
| wp_posts    | guid                  | 5361         | SQL  |
| wp_posts    | post_type             | 0            | SQL  |
| wp_posts    | post_mime_type        | 0            | SQL  |
+-------------+-----------------------+--------------+------+

問題なさそうなので、—dry-runオプションを外して置換します。

$ wp search-replace ‘{置換したいURL}’ '/' wp_posts wp_postmeta

管理画面にログインして、該当箇所が置換されていることと、問題なく動作することを確認できたら完了です。