2017-07-14 34 views
2

它不是那么多的正则表达式模式因为它是如何来实现它。我尝试过perl,sed和awk(各种各样的尝试),但我不确定这是多么可能作为一个单行(我宁愿不写一个perl脚本)。查找/替换两个标记字符串之间的字符串中的正则表达式

说我有

#MARKER_TOP 
INSERT INTO ('col1', 'col2', 'col3') 
VALUES 
(123,123,'2018-20-20 24:24:24',123) 
...etc. 
(123,123,'2018-20-20 24:24:24',123); 
#MARKER_BOTTOM 

...and more! (not all INSERT tables will be marked, btw) 

我想要做的是替换所有SQLS NOW()那些字符串日期。具体而言,用Perl,我已经试过如下:

perl -w -pi.bak -e "undef $/; s/(#MARKER_TOP.*)'[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]'(.*#MARKER_BOTTOM)/$1 NOW() $2/msg" test.sql

但它剥去所有的利息(#MARKER_TOP等)出块完全与NOW()代替该办法过于重手为了我想要的。

+0

你是什么意思“不是所有的INSERT表将被标记”? –

+2

我的意思是这些SQL语句中的一些(即'INSERT INTO ...')将不具有标记('MARKER_TOP,MARKER_BOTTOM'),该文件长达数千行并带有多个INSERT语句。那些没有标记的人不应该改变日期。 – Matt

回答

2

您可以使用awk这样的:

awk '/#MARKER_TOP/{m=1} /#MARKER_BOTTOM/{m=0} m{ 
    gsub(/\047[0-9]{4}(-[0-9]{2}){2} [0-9]{2}(:[0-9]{2}){2}\047/, "NOW()")} 1' file 

#MARKER_TOP 
INSERT INTO ('col1', 'col2', 'col3') 
VALUES 
(123,123,NOW(),123) 
...etc. 
(123,123,NOW(),123); 
#MARKER_BOTTOM 

下面是它的工作原理:

  • /#MARKER_TOP/{m=1}:设置一个标志m=1当我们得到的文本#MARKER_TOP
  • /#MARKER_BOTTOM/{m=0}:复位标志m=0当我们得到文字#MARKER_BOTTOM
  • m{gsub(/.../, "NOW()")}:当m==1然后用NOW()使用正则表达式
  • 1替换日期字符串:打印每个记录
+1

不错,但我认为封闭的'''也应该被删除。另一方面,Mawk不支持'{n}'。 – mklement0

+1

好的谢谢,更正单引号问题。希望OP不使用'mawk',否则正则表达式将不得不改变。 – anubhava

+1

@anubhava精美的作品。你介意解释一下(简要地)吗?我不熟悉'awk'。谢谢! – Matt

3

一个简单的方法是使用range operator

use warnings; 
use strict; 

my $file = 'test.sql'; 
open my $fh, '<', $file or die "Can't open $file: $!"; 

my $re_date = qr/'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'/; 

while (<$fh>) 
{ 
    if (/#MARKER_TOP/ .. /#MARKER_BOTTOM/) { 
     s/$re_date/NOW()/; 
    } 

    print; 
} 

或在一衬垫

perl -wpe"s/'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'/NOW()/ 
    if /#MARKER_TOP/ .. /#MARKER_BOTTOM/ 
" test.sql 

其中我用分隔代码3210所以能够在里面使用'(还有其他方法)。

我假定在一条线上有一个日期,严格按照问题中给出的格式,在''之内。我通过添加另一个INSERT部分进行了测试,但没有标记。替换只发生在标记 - 括号内。


范围操作符的工作方式是保持状态:一旦其左操作成真的话就变成真的,直到右操作数变成真实的,在这之后返回下一个迭代虚假它保持真实。它在标量上下文中以这种方式工作,而在列表上下文中它返回该范围内的列表。查看链接的文档。

+1

@Borodin Ouch,谢谢你......修复它... – zdim

相关问题