1

输入文件是

<section_begin>  mxsqlc


*** WARNING[13052] Cursor C is not fetched.
<section_end>
<section_begin>  b2.lst
*


*** WARNING[13052] Cursor C is not fetched.

0 errors, 1 warnings in SQL C file "b2.ppp".
<section_end>
<section_begin>  b2s0
SQLCODE=0
SQLSTATE=00000
a=10, b=abc, c=20
SQLCODE=0
SQLSTATE=00000
a=10, b=abc      , c=10, d=xyz      
<section_end>

期望没有以下行的输出。

<section_end>
<section_begin>  b2s0

我的代码是

perl -ne 'print unless /^\<section_end\>(\s*|.*lst)?\s*$/' b2exp

它删除所有<section_end>行并且不删除此行<section_begin> *.lst

4

2 回答 2

2

把事情简单化

perl -ne 'print unless /^\<section_/' b2exp

稍微复杂一点

perl -ne 'print unless /^\<section_(end|begin)\>/' b2exp

啊,你的问题不清楚。(对我来说,也许是真的)

<section_begin> tagname 我现在将其读作“我在开头和结尾标出了一些部分</section_end>。我希望在示例中排除具有特定标记名的部分bs20。我希望保留所有其他行”

perl -ne 'BEGIN {$p=1}  $p=0 if /section_begin.*b2s0/; print if $p; $p=1 if /<section_end>/;' ex.txt
于 2013-10-07T08:18:11.373 回答
0

如果打算将该部分与lst下一部分合并(并在下一部分的开始标记之后删除同一行上的内容),我会改用 Awk。

awk '/<section_end>/ && lst { next }
    /<section_begin>/ && lst { lst=0; next }
    /<section_begin>.*lst/ {lst=1}
    1' b2exp

当然,同样的事情可以在 Perl 中完成;由于缓冲,最简单的单线perl -0777 -pe 's/.../.../s' file器的内存效率会低得多。

perl -0777 -pe 's%(<section_begin>[^\n]*lst.*?)\n<section_end>\n<section_begin>[^\n]%$1%s' b2exp

这会将整个文件读入内存 ( -0777) 并替换多行正则表达式。贪婪匹配.*?将使匹配尽可能短,即不跨越模式其余部分的匹配(换行符、结束标记、换行符、开始标记可选地后跟非换行符数据)。我们还注意使用[^\n]我们希望在同一行上保持匹配的位置,因为/s标志变成.了一个通配符,它​​也可以匹配换行符。

于 2013-10-07T14:39:25.137 回答