SED匹配/替换URL和更新序列化数组计数

时间:2015-04-27 17:49:30

标签: arrays regex wordpress bash sed

以下是sql转储文件的示例代码段。此特定行包含Wordpress PHP序列化数组的meta_value。在dev。,test。和qc中的数据库恢复期间。环境我正在使用sed将URL替换为相应的环境子域。

INSERT INTO `wp_postmeta`
    (`meta_id`,
     `post_id`,
     `meta_key`,
     `meta_value`)
VALUES
    (527,
     1951,
     'ut_parallax_image',
     'a:4:{
          s:17:\"background-image\";
          s:33:\"http://example.com/background.jpg\";
          s:23:\"mobile-background-image\";
          s:37:\"www.example.com/mobile-background.jpg\";
      }')
;

但是,我需要扩展它以在更换后更正序列化数组中的字符串长度。

sed -r -e "s/:\/\/(www\.)?${domain}/:\/\/\1${1}\.${domain}/g" "/vagrant/repositories/apache/$domain/_sql/$(basename "$file")" > "/vagrant/repositories/apache/$domain/_sql/$1.$(basename "$file")"

对于开发人员来说,结果应如下所示:

INSERT INTO `wp_postmeta`
    (`meta_id`,
     `post_id`,
     `meta_key`,
     `meta_value`)
VALUES
    (527,
     1951,
     'ut_parallax_image',
     'a:4:{
          s:17:\"background-image\";
          s:37:\"http://dev.example.com/background.jpg\";
          s:23:\"mobile-background-image\";
          s:41:\"www.dev.example.com/mobile-background.jpg\";
      }')
;

除了sed之外,我不想引入任何依赖。

4 个答案:

答案 0 :(得分:1)

您的算法涉及算术。这使得sed成为一个糟糕的选择。请考虑使用awk

考虑这个输入文件:

$ cat inputfile
  something...
  s:33:\"http://example.com/background.jpg\";
  s:37:\"www.example.com/mobile-background.jpg\";
  s:33:\"http://www.example.com/background.jpg\";
  more lines...

我相信这可以做你想要的:

$ awk -F'"' '/:\/\/(www[.])?example.com/ {sub("example.com", "dev.example.com"); n=length($2)-1; sub(/:[[:digit:]]+:/, ":" n ":")} 1' inputfile 
  something...
  s:37:\"http://dev.example.com/background.jpg\";
  s:37:\"www.example.com/mobile-background.jpg\";
  s:41:\"http://www.dev.example.com/background.jpg\";
  more lines...

答案 1 :(得分:1)

WP-CLI在搜索替换http://wp-cli.org/commands/search-replace/期间处理序列化的PHP数组。我想尝试一个本机shell解决方案,但最后使用WP-CLI值得花费额外的开销。

答案 2 :(得分:0)

以下是您要求的示例文本文件(它是数据库导出)。

原创(https://www.example.com):

LOCK TABLES `wp_options` WRITE;
INSERT INTO `wp_options` VALUES (1,'siteurl','https://www.example.com','yes'),(18508,'optionsframework','a:48:{s:4:\"logo\";s:75:\"https://www.example.com/wp-content/uploads/2014/04/logo_imbrique_small3.png\";s:7:\"favicon\";s:62:\"https://www.example.com/wp-content/uploads/2017/04/favicon.ico\";}','yes')
/*!40000 ALTER TABLE `wp_options` ENABLE KEYS */;
UNLOCK TABLES;

需要的结果(http://example.localhost):

LOCK TABLES `wp_options` WRITE;
INSERT INTO `wp_options` VALUES (1,'siteurl','http://example.localhost','yes'),(18508,'optionsframework','a:48:{s:4:\"logo\";s:76:\"http://example.localhost/wp-content/uploads/2014/04/logo_imbrique_small3.png\";s:7:\"favicon\";s:64:\"https://example.localhost/wp-content/uploads/2017/04/favicon.ico\";}','yes');
/*!40000 ALTER TABLE `wp_options` ENABLE KEYS */;
UNLOCK TABLES;

如你所见:

  • 同一行出现多次
  • 转义字符不计入长度编号(例如:“/”)
  • 一些出现之前没有“s:”长度数字(无需替换,可以用awk后用简单的sed完成)

提前致谢!

答案 3 :(得分:0)

谢谢@ John1024。 @Fabio和@Seth,我不确定性能,但这些代码有效,没有wp-cli:

localdomain=mylittlewordpress.local
maindomain=strongwordpress.site.ru
cat dump.sql | sed 's/;s:/;\ns:/g' | awk -F'"' '/s:.+'$maindomain'/ {sub("'$maindomain'", "'$localdomain'"); n=length($2)-1; sub(/:[[:digit:]]+:/, ":" n ":")} 1' | sed ':a;N;$!ba;s/;\ns:/;s:/g' | sed "s/$maindomain/$localdomain/g" | mysql -u$USER -p$PASS $DBNAME

PHP序列化字符串由'; s爆炸:'通过@ John1024解决方案对多行字符串和awk处理所有行。

cat dump.sql | sed 's/;s:/;\ns:/g'

将输出重定向到awk

awk -F'"' '/^s:.+'$maindomain'/ {sub("'$maindomain'", "'$localdomain'"); n=length($2)-1; sub(/:[[:digit:]]+:/, ":" n ":")} 1'

处理完所有行后,多行内爆到一行(因此存在于原始dump.sql中)。谢谢@Zsolt https://stackoverflow.com/a/1252191

sed ':a;N;$!ba;s/;\ns:/;s:/g'

在wordpress数据库中添加sed替换需要任何其他字符串。

sed "s/$maindomain/$localdomain/g"

并加载到主服务器DB

... | mysql -u$USER -p$PASS $DBNAME