linux - bash 中的 PHP preg_replace,具体情况

标签 linux bash preg-replace sh

我需要清理包含 PHP 序列化值的 mysql 转储(我使用 sed 搜索/替换 url)

在 PHP 中我会这样做:

<?php

$ret_string = preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.mb_strlen('$2').':\"$2\";'", $string );

?>

你会如何在 bash 中做到这一点?

示例原始字符串:

a:3:{s:7:"string1";s:4:"test";s:3:"url";s:17:"http://myurl.com";s:7:"string2";s:‌​4:"test";} 

我已经用 mynewurl.com 替换了 myurl.com,所以它现在看起来像:

a:3:{s:7:"string1";s:4:"test";s:3:"url";s:17:"http://mynewurl.com";s:7:"string2";s:‌​4:"test";}

我需要更改的是字符串的长度,以反射(reflect)新字符串 (s:17) 的长度,以便最终字符串变为:

a:3:{s:7:"string1";s:4:"test";s:3:"url";s:19:"http://mynewurl.com";s:7:"string2"‌​;s:4:"test";}

我的 sql 转储中有很多这样的文件,它们是文件系统上的一个文件。虽然域名变了,但是url可能有额外的路径,因此字符串长度不同

最佳答案

在正则表达式中这样做的问题是正则表达式不适合结构化文本,如 JSON 或 PHP 序列化字符串。如果您知道您的输入数据将始终遵循某种结构,您就可以“伪造”事物,但是随着时间的推移,这样编写的代码会出现问题。事情总是随着时间而改变。如果您可以避免这种黑客行为,最好这样做。

我们到底想解决什么问题?您是否无法在需要进行此更改的主机上运行 PHP?序列化数据在 PHP 中将更容易处理,即使您制作了一个小的 shell 可执行 PHP 脚本来处理它。

[ghoti@pc ~]$ cat indexrepl
#!/usr/bin/env php
<?php

// Usage: indexrepl index newcontent [string]

if ($argc < 4) {
  $s='a:3:{s:7:"string1";s:4:"test";s:3:"url";s:16:"http://myurl.com";s:7:"string2";s:4:"test";}';
} else {
  $s=$argv[3];
}

$a=unserialize($s);
$a[$argv[1]]=$argv[2];

print serialize($a) . "\n";

[ghoti@pc ~]$ 
[ghoti@pc ~]$ 
[ghoti@pc ~]$ ./indexrepl url http://example.com/
a:3:{s:7:"string1";s:4:"test";s:3:"url";s:19:"http://example.com/";s:7:"string2";s:4:"test";}
[ghoti@pc ~]$ 
[ghoti@pc ~]$ s='a:3:{s:7:"string1";s:4:"test";s:3:"url";s:19:"http://example.com/";s:7:"string2";s:4:"test";}'
[ghoti@pc ~]$ ./indexrepl string1 foo "$s"
a:3:{s:7:"string1";s:3:"foo";s:3:"url";s:19:"http://example.com/";s:7:"string2";s:4:"test";}

更新:根据评论将其包装在外壳结构中:

[ghoti@pc ~]$ cat strings.txt
a:1:{s:3:"foo";s:3:"bar";}
a:1:{s:3:"foo";s:3:"baz";}
a:1:{s:3:"foo";s:5:"snert";}
[ghoti@pc ~]$ while read line; do ./indexrepl foo test "$line"; done < strings.txt
a:1:{s:3:"foo";s:4:"test";}
a:1:{s:3:"foo";s:4:"test";}
a:1:{s:3:"foo";s:4:"test";}
[ghoti@pc ~]$ 

关于linux - bash 中的 PHP preg_replace,具体情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11321438/

相关文章:

java - 如何创建一个 jar 。在类里面使用它。在命令行中使用 jar 执行类?

linux - Docker 中的 TCP、UDP 和 HTTP 服务器在启动容器后立即停止?

PHP如何删除下划线后文件名的最后一部分

php - 正则表达式仅检查每行的第一个匹配项

linux - 没有 shebang 行的 Shell 脚本工作正常吗?为什么?

Linux shell 脚本查找和重命名文件以删除后缀?

c++ - 有没有办法在 GTK3 应用程序中拥有 OpenGL 上下文?

linux - init.d 脚本停止 echo 管道到 grep 输出到终端

linux - 使用文件内容创建新目录

php - 去掉括号外的文字