Chinaunix首页 | 论坛 | 博客
  • 博客访问: 215515
  • 博文数量: 87
  • 博客积分: 192
  • 博客等级: 入伍新兵
  • 技术积分: 455
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-14 07:44
文章分类

全部博文(87)

文章存档

2013年(1)

2012年(86)

分类:

2012-04-14 15:39:39

原文地址:sed之SQL语句的复杂替换 作者:zooyo

原文本节选:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE think_user(id1 integer primary key, name2 text, comment text, owner text);
INSERT INTO "think_user" VALUES(1,'123',NULL,NULL);
CREATE TABLE think_user(id integer primary key, name text);
INSERT INTO "think_user" VALUES(1,'123');
 
删除CREATE TABLE的行并要取出表的字段名而且只保留字段名(红色部分),数据类型则不要,然后插入到INSERT INTO的行的表名后面,其他的行原样输出:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
INSERT INTO "think_user"(id1, name2, comment, owner) VALUES(1,'123',NULL,NULL);
INSERT INTO "think_user"(id, name) VALUES(1,'123');
 
 
  1. sed '/CREATE/{s/.*\((.*)\)./\1/;s/\([a-z]\+[0-9]*\) [^),]*\([,)]\)/\1\2/g;h;d};/INSERT/{G;s/\( VALUES.*\)\n\(.*\)/\2\1/}' file

[解析]

  这个谜底没揭晓之前我想用awk,当时真的是想屎了,在此谢谢Tim大师指点,言归正传,首先按照要求要对CREATE TABLE行进行操作,匹配到该行后先把我们要的字段截取出来:

s/.*\((.*)\)./\1/  --  (id1 integer primary key, name2 text, comment text, owner text)

这时候pattern space里的内容就是替换出来的这句,然后第2次替换,把字段名取出来,舍去字符串定义:

s/\([a-z]\+[0-9]*\) [^),]*\([,)]\)/\1\2/g  --  (id1, name2, comment, owner)

随后的h把paterrn space内容拷贝到缓冲区,d删除模版内容。

继续执行匹配到INSERT INTO的行,G把缓冲区的内容换行后附加到pattern space里:

INSERT INTO "think_user" VALUES(1,'123',NULL,NULL,NULL);
(id1, name2, passwd, comment, owner)

这就好办了吧,以\n为分割,把前后位置调换一下:

s/\( VALUES.*\)\n\(.*\)/\2\1/  --  INSERT INTO "think_user"(id1, name2, comment, owner) VALUES(1,'123',NULL,NULL);

大家注意,没有标记出的内容是不会有变化的。再次感谢Tim大师的指点和思路,谢谢您。

阅读(916) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~