首页 > 解决方案 > 如何使用 bash 命令在 xml 中的匹配模式后附加新标签

问题描述

考虑到我的 xml 内容如下:

要找到的模式 [说 patternString]:

        </secure-deployment>
        <% end %>

希望在匹配上述模式后附加以下 xml 内容:

要附加的模式* [说 appendingString]:

        <secure-deployment name="gvh-vid.war">
            <resource>gvh-vid</resource>
        </secure-deployment>

输出应采用以下格式:

        </secure-deployment>
        <% end %>
        <secure-deployment name="gvh-vid.war">
            <resource>gvh-vid</resource>
        </secure-deployment>

尝试使用以下语法的 awk 命令,它确实在匹配模式 [say patternString] 的每一行之后附加 [say appendingString],而不是在 macthed 模式之后附加内容:

IE

        awk '/<\/secure-deployment>/,/<% end %>/ {$0=$0"\n            <secure-deployment name=\"gvh-wid.war\">\n                <resource>gvh-vid<\/resource>\n            <\/secure-deployment>"} 1' standalone.xml.erb

观察到的输出:

        </secure-deployment>
        <secure-deployment name="gvh-vid.war">
            <resource>gvh-vid</resource>
        </secure-deployment>
        <% end %>
        <secure-deployment name="gvh-vid.war">
            <resource>gvh-vid</resource>
        </secure-deployment>

有人可以建议我用 awk 命令改进它吗?

标签: bashshell

解决方案


我不知道awk细节,但我认为问题在于你如何进行比赛:使用

/</secure-deployment>/,/<% end %>/

你正在制作一个OR,但AND如果我正确理解你的问题,你想要的是一个。

因此,我会将您的选择替换为:

/</secure-deployment>\s*<% end %>/

它期望两个标签是连续的,只能由任意数量的空格(包括换行符)分隔。


更新:我刚刚发现我提出的答案不起作用,并在评论中解释了原因。

所以最后的答案是:你不能改进你的 awk 脚本以在你的用例中工作,如果不引入非常糟糕的黑客,因为 awk 旨在一次输入一行

我试着为你写一个perl脚本来做同样的工作:

perl -0777p -i -e 's/^(.*?)(\s*<\/secure-deployment>\s*<% end %>)(.*?)$/\1\2\n        <secure-deployment name=\"gvh-wid.war\">\n            <resource>gvh-vid<\/resource>\n        <\/secure-deployment>\3/s' standalone.xml.erb

我承认这不是有史以来最清晰的脚本,但它应该可以工作......


推荐阅读