使用 sed 或 Perl 来注释 XML 块的正则表达式
Posted
技术标签:
【中文标题】使用 sed 或 Perl 来注释 XML 块的正则表达式【英文标题】:Regex using sed or Perl to comment XML Block 【发布时间】:2022-01-07 10:42:24 【问题描述】:我正在尝试仅使用 sed
或 perl -pi
(我唯一可用的工具)在 openAM 内的 web.xml 中评论一个部分。
所以,我在这里复制:
<servlet-mapping>
<servlet-name>AgentConfigurationServlet</servlet-name>
<url-pattern>/agentconfig/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>VersionServlet</servlet-name>
<url-pattern>/ccversion/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FSServlet</servlet-name>
<url-pattern>/federation/*</url-pattern>
</servlet-mapping>
但我试图只评论<servlet-mapping>...</servlet-mapping>
(但只有带有/ccversion 的评论。我尝试了所有方法,但无法使其正常工作。
我尝试了什么:
sed -e "s/(<servlet-mapping>[\r\n]+.*[\r\n]+.*\/ccversion.*[\r\n]+.*)/<\!-- \$1 -->/"
【问题讨论】:
【参考方案1】:您应该使用支持 XML 的工具来处理 XML。你提到 Perl,有几个 XML 处理模块可用。
但是,如果您坚持,请自担风险尝试以下操作:
perl -0777 -pe 's.*\K(<servlet-mapping>\s*.*?<url-pattern>/ccversion/.*?</servlet-mapping>)<!-- $1 -->s' file.xml
-0777
以“slurp 模式”读取文件,即读取整个文件,而不是逐行处理;
最初的.*\K
用于匹配并忘记我们感兴趣的<servlet-mapping>
之前的所有内容;
.*?
需要问号(“节俭量词”)只匹配最近的<url-pattern>
,同样第二个匹配最近的</servlet-mapping>
,而不是匹配到最后一个;
最后的 s
修饰符将点更改为也匹配换行符。
顺便说一句,在xsh 中,我碰巧维护了XML::LibXML 的包装,同样可以通过
open file.xml ;
for my $sm in //servlet-mapping[url-pattern="/ccversion/*"]
xinsert comment "$sm" replace $sm ;
save :b ;
【讨论】:
【参考方案2】:因为有人不得不说,我需要练习 :) 下面是如何使用 libxml 身份转换:
comment.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/info/servlet-mapping[url-pattern[text()='/ccversion/*']]">
<xsl:text disable-output-escaping="yes"><!-- </xsl:text>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:text disable-output-escaping="yes"> --></xsl:text>
</xsl:template>
</xsl:stylesheet>
xsltproc comment.xsl input.xml
输出
<?xml version="1.0"?>
<info>
<servlet-mapping>
<servlet-name>AgentConfigurationServlet</servlet-name>
<url-pattern>/agentconfig/*</url-pattern>
</servlet-mapping>
<!-- <servlet-mapping>
<servlet-name>VersionServlet</servlet-name>
<url-pattern>/ccversion/*</url-pattern>
</servlet-mapping> -->
<servlet-mapping>
<servlet-name>FSServlet</servlet-name>
<url-pattern>/federation/*</url-pattern>
</servlet-mapping>
</info>
【讨论】:
以上是关于使用 sed 或 Perl 来注释 XML 块的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 sed 或 perl 删除 `<a href="file://a>`keep this text`</a>`?
如何在两个模式之间打印线,包括或不包括(在 sed、AWK 或 Perl 中)?