只有当包含模式时,才能删除子串之间的文本(无论是在同一行还是多行)

时间:2016-07-14 11:56:18

标签: regex perl awk sed

文件中有一些数据(xml),我需要删除文本(不是整行,所以sed的/ d选项不适合)从Substring1到Substring2(包括两者)只有包含模式。 我的问题是可能有各种格式,因此Substring1和Substring2可以在同一行或不同,或者在同一行上可能有几对Substrin1 / 2。

示例(第1行 - 2对子串1/2和第1行包含PATTERN,第2行 - 1对与PATTERN,第3行 - 1对没有PATTERN,第4和第5行 - 1对与PATTERN,第6和第7行 - 1对没有PATTERN):

Substring1 = <?xml

Substring2 = </update>

模式= PATTERN

tmp.log
<?xml version="1.0" encoding="UTF-8" PATTERN-line1 <upd_date>2016-03-24</upd_date><upd_time>00:01:00.200</upd_time> blah-blah-blah </update><?xml version="1.0" encoding="UTF-8" blah-blah-blah-line1 <upd_date>2016-03-24</upd_date><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" PATTERN-line2 <upd_date>2016-03-24</upd_date><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line3 <upd_date>2016-03-24</upd_date><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" PATTERN-line4 <upd_date>2016-03-24</upd_date>
<upd_time>00:01:00.200</upd_time> blah-blah-blah-line5 </update>
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line6 <upd_date>2016-03-24</upd_date>
<upd_time>00:01:00.200</upd_time> blah-blah-blah-line7 </update>

Expected output:
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line1 <upd_date>2016-03-24</upd_date><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line3 <upd_date>2016-03-24</upd_date><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line6 <upd_date>2016-03-24</upd_date>
<upd_time>00:01:00.200</upd_time> blah-blah-blah-line7 </update>

我尝试了(没有完全成功)不同的组合,如下所示:

sed -i "s#<?xml.*PATTERN.*</update>##g" tmp.log

sed -i "#<?xml#{p; :a; N; #</update>#!ba; s#.*\n##}; p" tmp.log

perl -pi -e 's/<?xml.*PATTERN.*update>//' tmp.log

据我所知,当子串位于不同的行上时,这些会删除整行并跳过这种情况。我也没有在这里对PATTERN进行真正的检查。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:2)

gawk:

awk -v RS='<\\?xml' 'NR!=1 && !(/PATTERN/){print "<?xml",$0}'

答案 1 :(得分:1)

如果实际上还有,请使用XML的好模块。 XML::libXMLXML::Twig都非常出色。也就是说,这是直接解析。

use warnings;
use strict;

# Sample text for testing
my $text = q(start <?xml with PATTERN yes </update> and <?xml good </update> end); 

my $beg  = qr(<\?xml);
my $end  = qr(</update>);
my $patt = qr(PATTERN);

$text =~ s|$beg.*?$patt.*?$end||gs;

print "$text\n";

.*?非贪婪。修饰符/s处理换行符,使.与它们匹配。由于问题中的文字不清楚,我使用上面的$text作为输入:

start <?xml with PATTERN yes </update> and <?xml good </update> end

$text中输入此代码,上面的代码打印

start  and <?xml good </update> end

答案 2 :(得分:0)

请尝试这个:

use strict;
use warnings;

my $newDATA = "";
while(<DATA>)
{
    my $each_line = $_;  my $dump = $each_line;
        my ($pre,$match,$post) = "";
        while($each_line=~/<\?xml((?:(?!<\?xml|\n).)*)<\/update>/sg)
        {
            $pre = $pre.$`; $match=$&; $post = $'; my $dupmatch = $match;
            if($dupmatch=~m/PATTERN/i)
            {  $match = "";  }
            $pre = $pre.$match; $each_line = $post;
        }
        if(length $pre) {  $each_line = $pre.$post;  }
        $newDATA .= $each_line;
}
$newDATA=~s/\n{,1}/\n/g;
print $newDATA;

INPUT:

__DATA__
<?xml version="1.0" encoding="UTF-8" PATTERN-line1 <update>2016-03-24</update><upd_time>00:01:00.200</upd_time> blah-blah-blah </update><?xml version="1.0" encoding="UTF-8" blah-blah-blah-line1 <update>2016-03-24</update><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" PATTERN-line2 <update>2016-03-24</update><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line3 <update>2016-03-24</update><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" PATTERN-line4 <update>2016-03-24</update>
<upd_time>00:01:00.200</upd_time> blah-blah-blah-line5 </update>
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line6 <update>2016-03-24</update>
<upd_time>00:01:00.200</upd_time> blah-blah-blah-line7 </update>

输出:

<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line1 <update>2016-03-24</update><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line3 <update>2016-03-24</update><upd_time>00:01:00.200</upd_time> blah-blah-blah </update>
<upd_time>00:01:00.200</upd_time> blah-blah-blah-line5 </update>
<?xml version="1.0" encoding="UTF-8" blah-blah-blah-line6 <update>2016-03-24</update>
<upd_time>00:01:00.200</upd_time> blah-blah-blah-line7 </update>

您的XML标记非常不一致。请您检查一下以上的perl编码。