我正在使用webtool将Wordpress安装镜像到开发系统中。
目标是建立一个用于生产的Live系统和一个用于测试的开发系统。然后,webtool在这些系统之间提供一键同步。 每个系统都是独立的,具有自己的webroot,数据库和URL。
我在使用数据库转储时出现问题,我必须搜索所有对源的引用,并用目标的URL替换它们(例如:" www.example.com" - > ;" www-dev.example.com")。
我需要做的是:
查找网址的所有内容并将其替换为新网址。
如果匹配也匹配序列化字符串的格式,则应设置Field-Seperator,然后重新加载匹配项,以便可以在数组中设置实际长度。
在第一次尝试中,我试图通过“sed”来解决这个问题。命令如下:sed -i.orig 's/360\.example\.com/360-dev\.my\.example\.dev/g'
。
这没有用,因为转储中包含序列化数组,包含url。 sed
命令不利于更新序列化数组的字符串长度指示符。
我最近的尝试是使用建议here awk
,因为它能够进行算术运算。
我的awk
脚本如下所示:
/360[.]example[.]com/ {
sub("360.example.com", "360-dev.my.example.dev");
if ($0 ~ /s:[[:digit:]]+:["](http[s]?:\/\/)?360[.]example[.]com["]/){
FS="\"";
$0=$0;
n=length($2)-1;
sub(/:[[:digit:]]+:/, ":" n ":");
}
} 1
我的脚本中似乎有一些错误,我无法找到。它不会替换所有出现的url并完全跳过length-indicator-update。
如何修复脚本以实现我想要的目标?
编辑:(添加输入/输出样本)
Databasedump包含整个wordpress-database,每个表和记录都有CREATE TABLE IF NOT EXISTS
和INSERT
语句。
正常(未序列化)出现:
(36, 'home', 'http://360.example.com/blogname', 'yes'),
应该导致:
(36, 'home', 'http://360-dev.my.example.dev/blogname', 'yes'),
序列化发生:
(404, 'wp-maintenance-mode', 'a:21:{s:6:"active";i:1;s:4:"time";i:0;s:4:"link";i:1;s:7:"support";i:0;s:10:"admin_link";i:1;s:7:"rewrite";s:0:"";s:6:"notice";i:1;s:4:"unit";i:1;s:5:"theme";i:0;s:8:"styleurl";s:69:"http://360.example.com/wp-content/themes/blogname/css/maintenance.css";s:5:"index";i:0;s:5:"title";s:0:"";s:6:"header";s:0:"";s:7:"heading";s:0:"";s:4:"text";s:12:"Example Text";s:7:"exclude";a:1:{i:0;s:0:"";}s:6:"bypass";i:0;s:4:"role";a:1:{i:0;s:13:"administrator";}s:13:"role_frontend";a:1:{i:0;s:13:"administrator";}s:5:"radio";i:0;s:4:"date";s:0:"";}', 'yes'),
应该导致:
(404, 'wp-maintenance-mode', 'a:21:{s:6:"active";i:1;s:4:"time";i:0;s:4:"link";i:1;s:7:"support";i:0;s:10:"admin_link";i:1;s:7:"rewrite";s:0:"";s:6:"notice";i:1;s:4:"unit";i:1;s:5:"theme";i:0;s:8:"styleurl";s:76:"http://360-dev.my.example.dev/wp-content/themes/blogname/css/maintenance.css";s:5:"index";i:0;s:5:"title";s:0:"";s:6:"header";s:0:"";s:7:"heading";s:0:"";s:4:"text";s:12:"Example Text";s:7:"exclude";a:1:{i:0;s:0:"";}s:6:"bypass";i:0;s:4:"role";a:1:{i:0;s:13:"administrator";}s:13:"role_frontend";a:1:{i:0;s:13:"administrator";}s:5:"radio";i:0;s:4:"date";s:0:"";}', 'yes'),
编辑2:
现在使用wp-cli
来执行搜索和放大任务更换。
我有一个多站点设置,博客编号为(2,3,9)。
执行wp search-replace --url=360.example.com '360.example.com' '360-dev.my.example.dev'
会导致错误,告诉我无法找到单站点表(wp_redirection_items和wp_redirection_groups)。
这是事实,因为它们确实不存在,而是针对每个博客(例如:wp_2_redirection_items等)。该错误导致s& r中超过9000次错过发生。可以使用wp search-replace --url=360.example.com '360.example.com' '360-dev.my.example.com' wp_*
替换所有内容。但它仍然会引发错误。
答案 0 :(得分:3)
根据@archimiro的建议,现在任务由wp-cli完成。 但由于我还有一个多站点设置,导致一些错误,我不得不找出完整数据库搜索替换任务的命令。
最后的命令:
wp search-replace --url=360.example.com '360.example.com' '360-dev.my.example.dev' wp_*
。
如果没有明确告诉wp-cli在ALL(wp_*
)表中搜索和替换它会在抛出“找不到表”错误时停止。
答案 1 :(得分:0)
我过去使用过这个成功的方法:
sed 's|360\.example\.com|360-dev\.my\.example\.dev|g' com.sql > local.sql
编辑:抱歉没有awk,但也不是wp-cli。
答案 2 :(得分:0)
也不是awk或wpcli,但这是我写的一个php函数,似乎运行良好。
function snr($search, $replace, $inputfile, $outputfile){
$sql = file_get_contents($inputfile);
$sql1 = str_replace($search,$replace,$sql);
file_put_contents($outputfile,$sql1);
$serstrings = preg_split("/(?<=[{;])s:/",$sql1);
foreach($serstrings as $i=>$serstring) {
if (!!strpos($serstring, $replace)){
$justString = str_replace("\\","",str_replace("\\\\","j",explode('\\";',explode(':\\"',$serstring)[1])[0]));
$correct = strlen($justString);
$serstrings[$i] = preg_replace('/^\d+/',$correct, $serstrings[$i]);
}
}
file_put_contents($outputfile,implode("s:",$serstrings));
}