使用AWK安全地搜索和替换Wordpress SQL-Dump中的URL

时间:2017-08-21 13:08:24

标签: wordpress search awk replace command-line

我正在使用webtool将Wordpress安装镜像到开发系统中。

目标是建立一个用于生产的Live系统和一个用于测试的开发系统。然后,webtool在这些系统之间提供一键同步。 每个系统都是独立的,具有自己的webroot,数据库和URL。

我在使用数据库转储时出现问题,我必须搜索所有对源的引用,并用目标的URL替换它们(例如:" www.example.com" - > ;" www-dev.example.com")。

我需要做的是:

  1. 查找网址的所有内容并将其替换为新网址。

  2. 如果匹配也匹配序列化字符串的格式,则应设置Field-Seperator,然后重新加载匹配项,以便可以在数组中设置实际长度。

  3. 在第一次尝试中,我试图通过“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 EXISTSINSERT语句。

    正常(未序列化)出现:

    (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_*替换所有内容。但它仍然会引发错误。

3 个答案:

答案 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));
}