sed删除指定字符开头的行的上一行的指定字符

Table of Contents

最近在学习Oracle11g数据库时,需要将MySQL数据插入脚本转换成Oracle脚本,以在Oracle数据库中新建表和插入数据,方便练习。可是MySQL脚本太大,普通文本编辑器无法处理(7个G),于是用Linux下的sed老牌流编辑器,在我的DELL R710服务器上来做。

其中,有一段SQL脚本内容如下,


20000110119', '2016-02-04 02:00:01', '2016-02-04 02:00:00', '1200.00', '超时未领完');
INSERT INTO bonusreturnorder VALUES ('50', '254', '697', '2', '1', 'WX20160203085132174280', 'HBTK20160204020001045349', '2016-02-04 02:00:02', '2016-02-04 02:00:01', '600.00', '超时未领完');
--
  BONUSID number(11) ,
  DELETEFLAG number(2) ,
  TYPE number(2) ,
); 


CREATE TABLE bonususer (
--
  SENDUSERID number(11) ,
  SENDUSERNAME varchar2(32) ,
  BONUSTICKETNO varchar2(32) ,
); 

INSERT INTO bonususer VALUES ('332', '155', '100.00', '85705', '3', '2016-02-03 07:12:27', '2016-02-03 07:13:11', null, '1', '1322', null, 'HB201602030712277209291');
INSERT INTO bonususer VALUES ('335', '155', '100.00', '1322', '3', '2016-02-03 07:12:27', '2016-02-03 07:12:38', null, '1', '1322', null, 'HB201602030712277209292');
--
  receiveUserId number(11) NOT NULL,
  deleteFlag number(1) NOT NULL ,
  createTime date ,
); 

INSERT INTO rb_bon

 

要求:

使用sed删除以)开头的行的上一行末尾的逗号

苦恼了我两个晚上也没搞定,期间也参考了网上一些大神的博客和GNU官网sed命令的详解。最终选择在CSDN上发帖求助文本处理大神,迎刃而解。在此感谢大牛 “代码誉写工”。

答案:

[pc@S5 ~]$ sed '/,\s*$/{:loop; N; /,\(\s*\|\n\))/! bloop; s/,\s*[\n]\?\s*)/\n)/}' file
20000110119', '2016-02-04 02:00:01', '2016-02-04 02:00:00', '1200.00', '超时未领完');
INSERT INTO bonusreturnorder VALUES ('50', '254', '697', '2', '1', 'WX20160203085132174280', 'HBTK20160204020001045349', '2016-02-04 02:00:02', '2016-02-04 02:00:01', '600.00', '超时未领完');
--
  BONUSID number(11) ,
  DELETEFLAG number(2) ,
  TYPE number(2)
);


CREATE TABLE bonususer (
--
  SENDUSERID number(11) ,
  SENDUSERNAME varchar2(32) ,
  BONUSTICKETNO varchar2(32)
);

INSERT INTO bonususer VALUES ('332', '155', '100.00', '85705', '3', '2016-02-03 07:12:27', '2016-02-03 07:13:11', null, '1', '1322', null, 'HB201602030712277209291');
INSERT INTO bonususer VALUES ('335', '155', '100.00', '1322', '3', '2016-02-03 07:12:27', '2016-02-03 07:12:38', null, '1', '1322', null, 'HB201602030712277209292');
--
  receiveUserId number(11) NOT NULL,
  deleteFlag number(1) NOT NULL ,
  createTime date
);

INSERT INTO rb_bon

 

解释:

\s匹配空格、制表、换行、回车,也就是\s其实也匹配\n(多行模式的每行结尾)

\s*就是有0到n个空格或\n

/,/{}只要找到“,”就执行{}里的语句

:loop就是个标识,bloop 就是跳转到:loop

N是把下一行加入模式空间

/.\s*)/! bloop是如果模式空间发现了字符 “, )”,字符 “,” 和 “)” 之间也许有n多个空格和回车,但没有其它字符,就不再执行:loop循环,也就是不把下一行加入模式空间,而是执行bloop后的字符替换语句

s/,\s*)/\n)/ 就是去掉“,”号

----------------------------------------------------------------分割线------------------------------------------------------------------

关于扩展正则表达式匹配,GNU官网(http://www.gnu.org/software/sed/manual/sed.html#BRE-syntax)有解释,如下图,感兴趣的可以去研究下。