2

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";} 

myurl.comをmynewurl.comに置き換えたので、次のようになります。

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

変更する必要があるのは、最終的な文字列が次のようになるための新しい文字列の長さ(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に追加のパスがある可能性があるため、文字列の長さが異なります

4

2 に答える 2

1

正規表現でこれを行う場合の問題は、正規表現がJSONやPHPのシリアル化された文字列などの構造化テキストに適していないことです。入力データが常に特定の構造に従うことがわかっている場合は、「偽物」にすることができますが、そのように記述されたコードは、時間の経過とともに変化するため問題になります。そして、物事は常に時間とともに変化します。この種のハッキングを回避できる場合は、そうすることをお勧めします。

ここで解決しようとしている問題は正確に何ですか?この変更を行う必要のあるホストでPHPを実行できませんか?シリアル化されたデータは、シェルで実行可能な小さなPHPスクリプトを作成して処理する場合でも、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 ~]$ 
于 2012-07-04T03:45:45.210 に答える
0

私はphp-rソリューションに行き着きました。これをbashで行うと、多くの行があったと思います。

mv "$DATA_DIR/final.sql" "$DATA_DIR/final.sql.1"
php -r  "echo preg_replace('!s:(\\d+):\\\\\\\"(.*?)\\\\\\\";!e', \"'s:'.strlen( str_replace (array('\\\\r', '\\\\n', '\\\\t'), ' ', '\$2') ) .':\\\\\\\"\$2\\\\\\\";'\", file_get_contents('$DATA_DIR/final.sql.1') );" >"$DATA_DIR/final.sql"
rm "$DATA_DIR/final.sql.1";

それは私の場合はうまくいきます。

于 2012-07-04T23:21:22.900 に答える