用过滤器sed将mysql注释替换
问题
遇到这样的问题:我使用了某种工具生成出sql代码,生成出的代码是这样的:
DROP TABLE IF EXISTS FOO_TB;
CREATE TABLE FOO_TB(
f1 varchar(20) NOT NULL COMMENT '注释1',
f2 varchar(200) NULL COMMENT '注释2',
f3 varchar(500) NOT NULL COMMENT '类型',
f4 varchar(4000) NOT NULL COMMENT '内容',
f5 varchar(40) NOT NULL COMMENT '省份',
f6 varchar(20) NOT NULL COMMENT '日期',
f7 varchar(50) NULL COMMENT '号码',
f8 varchar(200) NULL COMMENT '名称')
COMMENT = '表';
这是mysql的sql,然而实际我要放到Sybase中运行这样的sql语句。我仍想保留注释内容,也就是说换成/*COMMENT '注释1'*/
这种,如何替换?
使用sed过滤器
考虑使用Linux下的sed
命令来解决此类文本过滤问题。 观察我们要替换的内容,分为两类,第一类是NOT NULL COMMENT '注释',
要替换成NOT NULL /*COMMENT '注释1'*/,
sed基本使用差不多是sed s/要替换内容/替换后内容/g
,这里我们遇到的要转义地方比较多,换成sed s#要替换内容#替换后内容#g
,这里的#换成!也可以。 另外,我们遇到还要使用到正则匹配的内容,匹配之前的注释
在我们匹配后依然也要把它加上,这就涉及到捕获组
的概念,1
是捕获组 ,就是第一个小括号内的值。 我们用.*
来匹配注释,同时用一对转义括号(
和)
把它们扩起来,在后面用1
再得到注释
内容。我们使用-i
命令使它原地替换。替换命令如下
sed -i "s#COMMENT '(.*)'([,)])#/*COMMENT 1*/2#g" test.sql
我们另外一类要替换的是COMMENT = '表';
,也就是后面接分号的。这么替换:
sed -i "s#(COMMENT = )'(.*)';#/*12*/;#g" test.sql
将多条sed命令合起来
sed提供了-e
选项,可以两条合并成一条,sed后面接-i和-e选项之后接两个引号引起来的正则表达式后面接文件名。
处理多文本情形
我使用的生成sql语句的工具一次会生成多个脚本,建表脚本会以[建表脚本]
开头,我们可以用[建表脚本]*.sql
去匹配所有建表脚本文件。
终极注释替换脚本
于是,我们得到最终的sed语句,以下语句可以把Mysql类型的COMMENT '注释1'
换成用/*
和*/
包裹注释内容的sql语句,从而用到sybase数据库上来建表。
sed -i -e "s#COMMENT '(.*)'([,)])#/*COMMENT 1*/2#g" -e "s#(COMMENT = )'(.*)';#/*12*/;#g" [建表脚本]*.sql
效果:
参考资料
- Unix & Linux大学教程(Harley Hahn's Guide to Unix and Linux)