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

sed regexp add xml comment around xml block

我有这个 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-->/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 工具

i dont have xml tools on my host only basic linux tools

在没有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>

解释:

  • /<datasource [^>]*app1/:匹配范围从 <datasource 标签开始,其中某处有文本 app1
  • ,/<\/datasource>/:范围以结束 </datasource> 标记结束。
  • {: 启动动作块
    • s/<datasource /<!--\n\t&/;:在开始 <datasource 标签前加上注释起始行 <!--
    • s~</datasource>~&\n\t-->~;:在结束 </datasource> 后附加注释结束行 -->
  • }: 结束动作块

使用您在 awk 中显示的示例,请尝试以下操作。

awk '
/<datasource.*pool-name="app1"/{ found=1 }
found{
  value=(value?value ORS:"")[=10=]
}
/<\/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:"")[=11=]                ##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