sed regexp 在 xml 块周围添加 xml 注释

Posted

技术标签:

【中文标题】sed regexp 在 xml 块周围添加 xml 注释【英文标题】:sed regexp add xml comment around xml block 【发布时间】:2021-10-17 22:29:03 【问题描述】:

我有这个 xml,我喜欢用字符串来评论 这是我的 xml(其中的一部分)

<subsystem
    xmlns="urn:jboss:domain:datasources:5.0">
    <datasources>
        <datasource jta="true" jndi-name="java:/comp/env/jdbc/app1" pool-name="app1" enabled="true"
                            use-ccm="false">
            <test1></test1>
            <test2></test2>
        </datasource>
         
            <datasource jta="true" jndi-name="java:/comp/env/jdbc/app2" pool-name="app2" enabled="true"
                            use-ccm="false"><test1></test1><test2></test2></datasource>
             
    </datasources>
</subsystem>

我尝试了这个 sed 正则表达式,但只能捕获第一个

sed -E '/./H;1h;$!d ; x ; s/(<datasource.*app1*)/ <!--\n\1-->/gi'

基于this 第 6.2 节

我喜欢捕捉并把它放在评论中,所以它看起来像这样

<subsystem
    xmlns="urn:jboss:domain:datasources:5.0">
    <datasources>
<!--
        <datasource jta="true" jndi-name="java:/comp/env/jdbc/app1" pool-name="app1" enabled="true"
                            use-ccm="false">
            <test1></test1>
            <test2></test2>
        </datasource>
-->

         
            <datasource jta="true" jndi-name="java:/comp/env/jdbc/app2" pool-name="app2" enabled="true"
                            use-ccm="false"><test1></test1><test2></test2></datasource>
             
    </datasources>
</subsystem>

更新 请不要关闭问题 我的主机上没有 xml 工具,只有基本的 linux 工具

【问题讨论】:

Don't Parse XML/html With Regex. 我建议使用 XML/HTML 解析器 (xmlstarlet, xmllint ...)。 我的主机中没有 xml,无法安装,sed 是我所拥有的 请不要关闭问题,因为我的主机上没有 xml 工具 【参考方案1】:

我的主机上没有 xml 工具,只有基本的 linux 工具

在没有 XML 解析工具的情况下,您可以使用这个基本的sed 命令来根据需要注释掉一个块。请记住,这不是 xmllint 等工具提供的强大解决方案。

你可以使用这个sed:

sed '/<datasource [^>]*app1/,/<\/datasource>/ s/<datasource /<!--\n\t&/; s~</datasource>~&\n\t-->~;' file.xml

<subsystem
    xmlns="urn:jboss:domain:datasources:5.0">
    <datasources>
    <!--
    <datasource jta="true" jndi-name="java:/comp/env/jdbc/app1" pool-name="app1" enabled="true"
                            use-ccm="false">
            <test1></test1>
            <test2></test2>
        </datasource>
    -->

            <datasource jta="true" jndi-name="java:/comp/env/jdbc/app2" pool-name="app2" enabled="true"
                            use-ccm="false"><test1></test1><test2></test2></datasource>

    </datasources>
</subsystem>

说明:

/&lt;datasource [^&gt;]*app1/:匹配范围从 &lt;datasource 标记开始,其中某处包含文本 app1 ,/&lt;\/datasource&gt;/:范围以结束 &lt;/datasource&gt; 标记结束。 :启动动作块 s/&lt;datasource /&lt;!--\n\t&amp;/;:在打开 &lt;datasource 标记前添加注释起始行 &lt;!-- s~&lt;/datasource&gt;~&amp;\n\t--&gt;~;:附加关闭 &lt;/datasource&gt; 与评论关闭行 --&gt; :结束动作块

【讨论】:

【参考方案2】:

您在awk 中显示的示例请尝试关注。

awk '
/<datasource.*pool-name="app1"/ found=1 
found
  value=(value?value ORS:"")$0

/<\/datasource>/ && found
  print "<!--" ORS value ORS "-->"
  value=found=""
  next

1
'  Input_file

说明:为上述添加详细说明。

awk '                                         ##Starting awk program from here.
/<datasource.*pool-name="app1"/ found=1     ##Checking if line contains <datasource till pool-name="app1" then set found to 1 here.
found                                        ##Checking if found is set then do following.
  value=(value?value ORS:"")$0                ##Creating value which has current line and keep concatenating its value to it.

/<\/datasource>/ && found                    ##If line contains </datasource> and found is set then do following.
  print "<!--" ORS value ORS "-->"            ##Printing comments section before and after value.
  value=found=""                              ##Nullifying value and found here.
  next                                        ##next will skip all further statements from here.

1                                             ##Printing current line here.
'  Input_file

【讨论】:

以上是关于sed regexp 在 xml 块周围添加 xml 注释的主要内容,如果未能解决你的问题,请参考以下文章

在 Snowflake 中使用 REGEXP_SUBSTR 在符号周围拉出多个项目,包括“(”

sed 删除影响文件中的所有行

Oracle Regexp - 替换周围的备份,但不是内部字符串

如何使用 sed 向每个 XML 节点添加命名空间

如何在圆形图像视图周围添加阴影

SED 如何用正则表达式替换 Line