SED 跨多行替换

Dou*_*eux 12 linux bash sed

我试图找到这三行:

<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->
Run Code Online (Sandbox Code Playgroud)

并将它们替换为:

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
Run Code Online (Sandbox Code Playgroud)

当我尝试

sudo sed -i 's:<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml
Run Code Online (Sandbox Code Playgroud)

它没有找到它,我也尝试将 \n 放入其中,但它仍然不起作用:

sudo sed -i 's:<!--\n <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />\n -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml
Run Code Online (Sandbox Code Playgroud)

这些不会引发任何错误,只是不会取消注释该行。任何建议都会有所帮助谢谢!

Edu*_*nec 6

Sed 逐行工作。它可以在多行上工作,但它不是那样设计的——在我看来,当你尝试这样使用时,它肯定会显示出来。但是,如果您决定采用这种方式,则可能必须使用寄存器。检查/sf/ask/87639961/ 的一些解决方案以了解如何完成。

我更喜欢使用 perl 而不是 sed 来完成这种任务(我的意思是面向多行)。您必须在搜索和替换 ( BEGIN...)之前添加的样板并不明显,但正则表达式对我来说似乎更清晰:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml
Run Code Online (Sandbox Code Playgroud)

或者,使用分组来缩短表达式并允许您在那里使用正则表达式:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->/\1/smg' file.xml
Run Code Online (Sandbox Code Playgroud)

它应该适用于注释标记和要取消注释的代码之间有和没有换行符的出现。

改编自:

/sf/ask/72155121/


Gil*_*il' 6

sed 依次读取每一行,因此它永远不会匹配多行模式,除非您将其推向正确的方向。该N命令从输入中读取一行并将其附加到模式空间。

sed -i -e '/^<!--$/ {
    N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
        N; /\n-->$/ {
            s/^<!--\n//; s/\n-->$//
        }
    }
}' /myfile.xml
Run Code Online (Sandbox Code Playgroud)

可以说,如果您需要除 之外的命令s,那么您应该从 sed 切换到 awk 或 perl。这是一个稍微灵活的 Perl 片段,它以更通用的方式处理多行注释。

perl -i -pe '
    if (/<!--/) { $_ .= <> while !/-->/;
        s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
    }' /myfile.xml
Run Code Online (Sandbox Code Playgroud)