用groovy替换特定的文件行

时间:2015-07-02 04:23:00

标签: groovy

我有2个文件(long.xmlsort.xml文件),格式相同:

<?xml version="1.0" encoding="UTF-8"?>
<psf version="2.0">
<provider id="org.eclipse.team.cvs.core.cvsnature">
<project reference="1.0,:pserver:url:/cvs/SynBusStop,Account Interest,Account Interest,branch_A_B"/>
<project reference="1.0,:pserver:url:/cvs/SynInf,ActiveMQ Libraries,ActiveMQ Libraries,branch_A_B"/>
<project reference="1.0,:pserver:url:/cvs/SynBusStop,Alert,Alert,branch_B_B"/>
<project reference="1.0,:pserver:url:/cvs/SynBusStop,Alert Adaptor,Alert Adaptor,branch_A_B"/>
<project reference="1.0,:pserver:url:/cvs/SynInf,Ant Extensions Syn,Ant Extensions Syn,branch_A_B"/>
</provider>
</psf>`

sort.xml中的所有内容都应位于long.xml

我想写一个script来查找sort.xml,以便我可以将新信息从sort.xml更新为long.xml(通常更新分支)。这是我的剧本:

def source = new File('Path:\\sort.xml')
def dest = new File('Path:\\long.xml')
text = dest.text
text.eachLine
{

    if(it.contains("/cvs/SynBusStop,Account Interest,"))
    {
        println it
        text = text.replace("branch_A_B", "new_Branch")
        dest.write(text);
    }   

}

`

但它已经替换了包含branch_A_B的每一行。在这种情况下,任何人都可以帮助我,我是Groovy的新手,提前谢谢你。

2 个答案:

答案 0 :(得分:0)

在您的代码中,您有text = text.replace("branch_A_B", "new_Branch"),它确实会替换整个文件中的所有匹配项。

如果您想继续使用您的策略而不是体验XML解析,您可以尝试逐行替换。像这样:

def strIn =“”“                                                                                                                                  `         “”“

    def strOut ="";

    strIn.eachLine{
        println "-->"+it
        if(it.contains("/cvs/SynBusStop,Account Interest,"))
        {
            it = it.replace("branch_A_B", "new_Branch")
            println "-->CHANGED: "+it
        }
        strOut+=it+"\n";
    }

    println "Result: "+strOut

输出:

-->
-->         <?xml version="1.0" encoding="UTF-8"?>
-->         <psf version="2.0">
-->         <provider id="org.eclipse.team.cvs.core.cvsnature">
-->         <project reference="1.0,:pserver:url:/cvs/SynBusStop,Account Interest,Account Interest,branch_A_B"/>
-->CHANGED:             <project reference="1.0,:pserver:url:/cvs/SynBusStop,Account Interest,Account Interest,new_Branch"/>
-->         <project reference="1.0,:pserver:url:/cvs/SynInf,ActiveMQ Libraries,ActiveMQ Libraries,branch_A_B"/>
-->         <project reference="1.0,:pserver:url:/cvs/SynBusStop,Alert,Alert,branch_B_B"/>
-->         <project reference="1.0,:pserver:url:/cvs/SynBusStop,Alert Adaptor,Alert Adaptor,branch_A_B"/>
-->         <project reference="1.0,:pserver:url:/cvs/SynInf,Ant Extensions Syn,Ant Extensions Syn,branch_A_B"/>
-->         </provider>
-->         </psf>`
-->     
Result: 
            <?xml version="1.0" encoding="UTF-8"?>
            <psf version="2.0">
            <provider id="org.eclipse.team.cvs.core.cvsnature">
            <project reference="1.0,:pserver:url:/cvs/SynBusStop,Account Interest,Account Interest,new_Branch"/>
            <project reference="1.0,:pserver:url:/cvs/SynInf,ActiveMQ Libraries,ActiveMQ Libraries,branch_A_B"/>
            <project reference="1.0,:pserver:url:/cvs/SynBusStop,Alert,Alert,branch_B_B"/>
            <project reference="1.0,:pserver:url:/cvs/SynBusStop,Alert Adaptor,Alert Adaptor,branch_A_B"/>
            <project reference="1.0,:pserver:url:/cvs/SynInf,Ant Extensions Syn,Ant Extensions Syn,branch_A_B"/>
            </provider>
            </psf>`

答案 1 :(得分:0)

您的代码存在的问题是您在整个文件文本中使用replace方法。你应该只在你想要的那一行上做到这一点:

def source = new File('Path:\\sort.xml')
def dest = new File('Path:\\long.xml')
def newLines = []

dest.eachLine { line ->
    if(line.contains("/cvs/SynBusStop,Account Interest,")) {
        println line
        line = line.replace("branch_A_B", "new_Branch")
    }
    newLines << line
}

dest.withWriter { out ->
    newLines.each { out.println it }
}

关于这两个文件之间的差异,这很大程度上取决于您希望解决方案的通用性。也许您可以使用diff and patch经典方式解决此问题。如果文件不大,您可以在Map中存储行并进行比较,或者您可以使其更具体processing XML