替换可能的多行模式的每一行的开头

时间:2019-04-02 19:38:41

标签: perl substitution

我正在尝试匹配多行模式,并修改与该模式匹配的每一行,包括第一行,以便将字符添加到该行的开头(+/-

例如,我有:

stuff above
<span>one-liner span</span>
stuff middle
    <span>stuff inside
    other stuff
    </span>
stuff below

我想获得它:

stuff above
+ <span>one-liner span</span>
stuff middle
+     <span>stuff inside
+     other stuff
+     </span>
stuff below

到目前为止,我在那里:

perl -n0e 's/\n(.*<span style="color: green".*?<\/span>)/+$1/g && print' myfile.html

这里的问题是它只修改第一行,如果是多行模式,我想修改所有行。

任何想法如何做到这一点?

我正在使用perl,但如果您认为更好,可以使用其他工具。

谢谢!

3 个答案:

答案 0 :(得分:2)

一种方法是使用range operator

perl -wpe'print "+ " if /^\s*<span/ .. /<\/span>/' file

在这种情况下,..运算符保持其状态,因此

  

一旦左操作数为true,范围运算符将保持为true,直到右操作数为true,此后范围运算符将再次变为false。

它的典型用途是精确地选择由给定条件界定的行范围。

在这里,我将开头span限制为该行上的第一个非空白内容,但没有将其结尾的内容限制为允许一行<span ...>word</span>起作用。 / p>

答案 1 :(得分:1)

使用范围运算符可遮盖所需的范围,然后将其附加到以空格开头的行。这段代码并没有给出您想要的,但是会为您指明正确的方向。

while(<>) {
    if( /stuff above/ .. /stuff below/ ){
        $_= "+".$_ if /^ +/;
        print $_;
    }
}

范围运算符是我的最爱之一!

答案 2 :(得分:0)

如果您的数据位于“ d”文件中

perl -ne 'if (/^\s*<(span)>.*?(<\/\1>)?\s*$/) {print "+$&";next if ($2);$t="</$1>";do{$_=<>;print "+$_"} until(/$t/) } else {print}' d

gnu sed

sed -E 's/<(span)>.*<\/\1>/+&/;Tc;b ;:c /^\s*<span>/{s/^/+/;:l n;s/^/+/;/<\/span>/!bl}' d
相关问题