You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并sed命令批量修改XML文件适配SonarQube?

合并sed命令并转换XML适配SonarQube

需求概述

Mac环境下,需将个人项目的XML覆盖率文件修改格式以适配SonarQube。当前已有多个分散的sed命令实现部分需求,希望合并为更少的文件操作;尝试过xmlstarlet,但会删除整个节点块,仅需删除特定行。需完成的具体修改:

  • 合并删除命令(利用sed的OR逻辑)
  • 将class替换为file
  • 修改<coverage>行的version值为1
  • 额外适配:将<line>转换为<lineToCover>、调整相关属性名(如line-rate→lineToCover-rate等)

现有分散命令

# 删除特定行
sed -i '' '/classes/d' coverage.xml
sed -i '' '/lines&gt;/d' coverage.xml
sed -i '' '/&lt;method/d' coverage.xml
sed -i '' '/package/d' coverage.xml
sed -i '' '/source/d' coverage.xml
sed -i '' '/&lt;source/d' coverage.xml

# 替换class为file
sed -i '' 's/class/file/g' coverage.xml

# 修改coverage版本
sed -i '' '/&lt;coverage/s/version=&quot;2.0.3&quot;/version=&quot;1&quot;/g' coverage.xml 

原始XML

&lt;?xml version=&quot;1.0&quot; ?&gt;
&lt;!DOCTYPE coverage
SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-04.dtd'&gt;
&lt;coverage branch-rate=&quot;0.0&quot; branches-covered=&quot;0&quot; branches-valid=&quot;0&quot; complexity=&quot;0&quot; line-rate=&quot;0.5936254980079682&quot; lines-covered=&quot;447&quot; lines-valid=&quot;753&quot; timestamp=&quot;1672197709&quot; version=&quot;2.0.3&quot;&gt;
    &lt;packages&gt;
        &lt;package line-rate=&quot;0.7614678899082569&quot; branch-rate=&quot;0.0&quot; name=&quot;src.services.secrets.keys&quot; complexity=&quot;0&quot;&gt;
            &lt;classes&gt;
                &lt;class branch-rate=&quot;0.0&quot; complexity=&quot;0&quot; filename=&quot;src/services/guava/keys/keys.go&quot; line-rate=&quot;0.7614678899082569&quot; name=&quot;src.services.guava.keys.keys.go&quot;&gt;
                    &lt;methods/&gt;
                    &lt;lines&gt;
                        &lt;line branch=&quot;false&quot; hits=&quot;0&quot; number=&quot;109&quot;/&gt;
                        &lt;line branch=&quot;false&quot; hits=&quot;0&quot; number=&quot;123&quot;/&gt;
                    &lt;/lines&gt;
                &lt;/class&gt;
            &lt;/classes&gt;
        &lt;/package&gt;
        &lt;package line-rate=&quot;0.5944055944055944&quot; branch-rate=&quot;0.0&quot; name=&quot;src.services.guava.vault&quot; complexity=&quot;0&quot;&gt;
            &lt;classes&gt;
                &lt;class branch-rate=&quot;0.0&quot; complexity=&quot;0&quot; filename=&quot;src/services/secrets/vault/vault.go&quot; line-rate=&quot;0.5944055944055944&quot; name=&quot;src.services.guava.vault.vault.go&quot;&gt;
                    &lt;methods/&gt;
                    &lt;lines&gt;
                        &lt;line branch=&quot;false&quot; hits=&quot;1&quot; number=&quot;251&quot;/&gt;
                        &lt;line branch=&quot;false&quot; hits=&quot;1&quot; number=&quot;253&quot;/&gt;
                    &lt;/lines&gt;
                &lt;/class&gt;
            &lt;/classes&gt;
        &lt;/package&gt;
    &lt;/packages&gt;
&lt;/coverage&gt;

期望适配SonarQube的XML

&lt;?xml version=&quot;1.0&quot; ?&gt;
&lt;!DOCTYPE coverage
  SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-04.dtd'&gt;
&lt;coverage branch-rate=&quot;0.0&quot; branches-covered=&quot;true&quot; branches-valid=&quot;0&quot; complexity=&quot;0&quot; lineToCover-rate=&quot;0.5936254980079682&quot; lineToCovers-covered=&quot;447&quot; lineToCovers-valid=&quot;753&quot; timestamp=&quot;1672173715&quot; version=&quot;1&quot;&gt;
        &lt;file branch-rate=&quot;0.0&quot; complexity=&quot;0&quot; path=&quot;src/services/guava/keys/keys.go&quot; lineToCover-rate=&quot;0.7614678899082569&quot; name=&quot;src.services.guava.keys.keys.go&quot;&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;false&quot; lineNumber=&quot;16&quot;/&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;false&quot; lineNumber=&quot;17&quot;/&gt;
        &lt;/file&gt;
        &lt;file branch-rate=&quot;0.0&quot; complexity=&quot;0&quot; path=&quot;src/services/guava/server/server.go&quot; lineToCover-rate=&quot;0.744&quot; name=&quot;src.services.guava.server.server.go&quot;&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;false&quot; lineNumber=&quot;153&quot;/&gt;
        &lt;/file&gt;
        &lt;file branch-rate=&quot;0.0&quot; complexity=&quot;0&quot; path=&quot;src/services/secrets/tools/keyrotate/cmd_get.go&quot; lineToCover-rate=&quot;0.0&quot; name=&quot;src.services.guava.tools.keyrotate.cmd_get.go&quot;&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;true&quot; lineNumber=&quot;16&quot;/&gt;
        &lt;/file&gt;
        &lt;file branch-rate=&quot;0.0&quot; complexity=&quot;0&quot; path=&quot;src/services/secrets/tools/keyrotate/cmd_rotate.go&quot; lineToCover-rate=&quot;0.72&quot; name=&quot;src.services.guava.tools.keyrotate.cmd_rotate.go&quot;&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;false&quot; lineNumber=&quot;75&quot;/&gt;
        &lt;/file&gt;
        &lt;file branch-rate=&quot;0.0&quot; complexity=&quot;0&quot; path=&quot;src/services/secrets/tools/keyrotate/main.go&quot; lineToCover-rate=&quot;0.0&quot; name=&quot;src.services.guava.tools.keyrotate.main.go&quot;&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;true&quot; lineNumber=&quot;80&quot;/&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;true&quot; lineNumber=&quot;81&quot;/&gt;
        &lt;/file&gt;
        &lt;file branch-rate=&quot;0.0&quot; complexity=&quot;0&quot; path=&quot;src/services/guava/vault/vault.go&quot; lineToCover-rate=&quot;0.5944055944055944&quot; name=&quot;src.services.guava.vault.vault.go&quot;&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;false&quot; lineNumber=&quot;251&quot;/&gt;
                &lt;lineToCover branch=&quot;false&quot; covered=&quot;false&quot; lineNumber=&quot;253&quot;/&gt;
        &lt;/file&gt;
&lt;/coverage&gt;

优化后的单条sed命令

将所有操作合并为一次文件读写,利用sed的\|实现OR逻辑匹配删除行,通过-e参数串联多个修改动作:

sed -i '' -e '/classes\|lines&gt;\|&lt;method\|package\|source\|&lt;source/d' \
           -e 's/class/file/g' \
           -e '/&lt;coverage/s/version=&quot;2.0.3&quot;/version=&quot;1&quot;/g' \
           -e 's/line-rate/lineToCover-rate/g' \
           -e 's/lines-covered/lineToCovers-covered/g' \
           -e 's/lines-valid/lineToCovers-valid/g' \
           -e 's/filename=&quot;/path=&quot;/g' \
           -e 's/&lt;line branch=&quot;\([^&]*\)&quot; hits=&quot;\([0-9]*\)&quot; number=&quot;\([0-9]*\)&quot;/&lt;lineToCover branch=&quot;\1&quot; covered=&quot;\2&quot; lineNumber=&quot;\3&quot;/g' coverage.xml

命令说明

  1. 删除行:用\|分隔所有需要删除的行匹配模式,一次删除所有目标行
  2. 替换class为file:全局替换所有class字符串为file
  3. 修改coverage版本:仅匹配<coverage>行,替换版本号
  4. 调整属性名:将SonarQube不兼容的属性名替换为目标格式
  5. 转换行节点:将<line>节点转换为<lineToCover>,并调整属性(hits转covered,number转lineNumber)

内容的提问来源于stack exchange,提问作者AhmFM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:55:24