2012-10-15 46 views
5

我想将匹配结果的特定部分存储为稍后用于替换的变量。我希望将它保留在一行中,而不是在事先找到我需要的变量。配置Apache的时候,和使用mod_rewrite,你可以specificy的模式特定部分在sed命令中使用占位符/变量

用作变量,像这样:

RewriteRule ^www.example.com/page/(.*)$ http://www.example.com/page.php?page=$1 [R=301,L] 

多数民众赞成包含在括号内的模式匹配的部分存储用$ 1供以后使用。所以如果网址是www.example.com/page/home,它将被替换为www.example.com/page.php?page=home。所以比赛的“主场”部分被保存在$ 1中,因为它是括号内模式的一部分。

我想要这样的功能与sed命令,我需要自动替换SQL转储文件中的许多字符串,以添加删除表,如果在每个创建表之前存在的命令,但我需要知道表名称做这一点,所以如果转储文件包含类似:

... 
CREATE TABLE `orders` 
... 

我需要运行类似:

cat dump.sql | sed "s/CREATE TABLE `(.*)`/DROP TABLE IF EXISTS $1\N CREATE TABLE `$1`/g" 

得到的结果是:

... 
DROP TABLE IF EXISTS `orders` 
CREATE TABLE `orders` 
... 

我在sed命令中使用mod_rewrite语法作为我试图做的一个逻辑例子。

有什么建议吗?

回答

8
sed '/CREATE TABLE \([^ ]*\)/ s//DROP TABLE IF EXISTS \1; &/' 

查找CREATE TABLE语句并捕获表名。将它替换为'DROP TABLE IF EXISTS'和表名,再加上一个分号来终止语句,以及匹配的副本以保留CREATE TABLE语句。

这是经典的sed表示法。由于您使用的是bash,因此您有可能使用GNU sed,并且需要添加--posix才能使用该表示法,否则您需要使用脚本来使用GNU的非标准sed正则表达式。我也没有试图在输出中插入换行符。如果GNU sed对您来说足够重要,您可以使用GNU sed

关键是圆括号(通常需要用反斜线转义)是捕获机制,而反斜杠数是替代机制。

+0

感谢您对此的解释,它已经完全回答我的问题。 –

6
sed -r "s/CREATE TABLE (\`.*\`)/DROP TABLE IF EXISTS \1\n &/g" dump.sql 

测试

kent$ cat t.txt 

CREATE TABLE `orders` 
... 

CREATE TABLE `foo` 
... 
... 

CREATE TABLE `bar` 
... 


kent$ sed -r "s/CREATE TABLE (\`.*\`)/DROP TABLE IF EXISTS \1\n &/g" t.txt 

DROP TABLE IF EXISTS `orders` 
CREATE TABLE `orders` 
... 

DROP TABLE IF EXISTS `foo` 
CREATE TABLE `foo` 
... 
... 

DROP TABLE IF EXISTS `bar` 
CREATE TABLE `bar` 
... 
+0

谢谢,这是一个很好的例子。 –